Jelaskan perintah shell: shift $ (($ optind - 1))


30

Saya bukan orang Linux tetapi terjebak dalam beberapa Script yang harus saya baca untuk Proyek saya. Jadi adakah yang bisa membantu saya apa yang dilakukan perintah ini?

shift $(($optind - 1))

3
Seperti disebutkan di bawah, OPTIND harus dalam huruf besar dan '$' di dalam tanda kurung adalah opsional.
DarkHeart

Jawaban:


49

shift $((OPTIND-1))(note OPTINDadalah huruf besar) biasanya ditemukan segera setelah satu getopts whileloop. $OPTINDadalah jumlah opsi yang ditemukan oleh getopts.

Seperti yang disebutkan pauljohn32 dalam komentar, secara tegas, OPTINDmemberikan posisi argumen baris perintah berikutnya .

Dari Manual Referensi Bash GNU :

getopts optstring name [args]

getoptsdigunakan oleh skrip shell untuk mengurai parameter posisi. optstringberisi karakter opsi untuk dikenali; jika karakter diikuti oleh titik dua, opsi diharapkan memiliki argumen, yang harus dipisahkan darinya oleh spasi. Tanda titik dua (':') dan tanda tanya ('?') Tidak boleh digunakan sebagai karakter opsi. Setiap kali dipanggil, getoptstempat opsi berikutnya dalam nama variabel shell, inisialisasi namejika tidak ada, dan indeks argumen berikutnya untuk diproses menjadi variabel OPTIND. OPTINDdiinisialisasi ke 1 setiap kali shell atau script shell dipanggil. Ketika opsi membutuhkan argumen, getopts menempatkan argumen itu ke dalam variabel OPTARG. Shell tidak meresetOPTIND secara otomatis; itu harus secara manual mengatur ulang antara beberapa panggilan ke getoptsdalam permintaan shell yang sama jika satu set parameter baru akan digunakan.

Ketika akhir opsi ditemukan, getoptskeluar dengan nilai kembali lebih besar dari nol. OPTINDdiatur ke indeks argumen non-opsi pertama, dan nama diatur ke '?'.

getoptsbiasanya mem-parsing parameter posisi, tetapi jika lebih banyak argumen diberikan args, getoptsparsing itu sebagai gantinya.

shift n
menghapus n string dari daftar parameter posisi. Dengan demikian shift $((OPTIND-1))menghapus semua opsi yang telah diuraikan oleh getoptsdari daftar parameter, dan setelah titik itu, $1akan merujuk pada argumen non-opsi pertama yang diteruskan ke skrip.

Memperbarui

Seperti mikeserv menyebutkan dalam komentar, shift $((OPTIND-1))bisa jadi tidak aman. Untuk mencegah pemisahan kata yang tidak diinginkan dll, semua ekspansi parameter harus dikutip ganda. Jadi bentuk aman untuk perintah adalah

shift "$((OPTIND-1))"


Sepertinya ini hanya akan berfungsi dengan baik jika semua opsi muncul sebelum argumen posisi yang tersisa. Benar?
Steve Jorgensen

@SteveJorgensen: Ya, itu benar. OTOH, menempatkan opsi setelah argumen non-opsi bertentangan dengan konvensi sh / bash. Secara umum, argumen pertama yang tidak dimulai dengan tanda hubung menandakan akhir dari opsi, dan argumen berikutnya yang dimulai dengan tanda hubung tidak dianggap sebagai opsi. Tidak semua program mematuhi konvensi ini, tetapi itu membuat hidup jauh lebih mudah jika Anda melakukannya. :)
PM 2Ring

@SteveJorgensen: (lanjutan) Topik ini dibahas secara singkat di Mengapa beberapa utilitas mengurai operan sebelum opsi? . Seperti komentar Gilles untuk jawaban Celada yang menyebutkan, beberapa program (seperti find) mungkin terlihat seperti mereka mengizinkan opsi setelah non-opsi, tetapi mereka tidak: mereka memiliki operan yang dimulai dengan tanda hubung.
PM 2Ring

Terima kasih atas info (& hasil edit) @mosvy Itu sangat tidak biasa IFS, tetapi lebih baik aman daripada menyesal. ;)
PM 2Ring

@roaima jika IFS=0123456789, shift $((OPTIND-1))(tanpa tanda kutip) akan berubah menjadi shift ""mana yang akan diabaikan (dalam ksh) secara diam-diam atau menghasilkan kesalahan (dalam bashdan dash).
Mosvy

8

$((...))hanya menghitung barang. Dalam kasus Anda dibutuhkan nilai $optintdan kurang 1.

shiftmenghapus parameter posisi. Dalam kasus Anda itu menghapus optint-1parameter.

Untuk informasi lebih lanjut kita lihat help getopts, help shift, lihat man bashuntuk "Ekspansi Aritmatika", dan terutama google untuk getopts.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.