Saya ingin memanggil myscript
file dengan cara ini:
$ ./myscript -s 45 -p any_string
atau
$ ./myscript -h #should display help
$ ./myscript #should display help
Persyaratan saya adalah:
getopt
di sini untuk mendapatkan argumen masukan- periksa yang
-s
ada, jika tidak kembalikan kesalahan - periksa apakah nilainya setelah
-s
45 atau 90 - periksa apakah
-p
ada dan setelah itu ada string input - jika pengguna masuk
./myscript -h
atau baru saja./myscript
menampilkan bantuan
Saya mencoba sejauh ini kode ini:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Tetapi dengan kode itu saya mendapatkan kesalahan. Bagaimana cara melakukannya dengan Bash dan getopt
?
-s
, membuat argumen posisi:./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
sebenarnya merupakan opsi (yaitu, program Anda dapat melanjutkan jika tidak ada). Dalam hal ini./myscript 45 -p any_string
,. (Saya pikir itugetopt
dapat menangani opsi campuran dan argumen posisi, sedangkanbash
perintahgetopts
Jawaban:
Contoh berjalan:
sumber
usage()
benar-benar mengembalikan 1?-h
harus kembali0
, setelah memukul bendera yang tidak ada itu harus kembali>0
(demi kesederhanaan saya tidak membedakan antara kasus-kasus dan tidak ada yang memaksa Anda untuk mencetak teks penggunaan dalam kasus terakhir) . Saya telah melihat program yang selalu kembali!= 0
, meskipun, bahkan pada-h/--help
. Mungkin saya harus memperbarui snippet kalau-kalau orang menggunakan ini sebagai boilerplate (saya harap tidak)?getopts
desain ( '), tidak ada yang namanya "argumen opsional" dengangetopts
. Parser tidak bisa tahu apakah token berikutnya adalah argumen untuk opsi saat ini atau opsi sendiri karena-p
mungkin nilai yang dimaksud. Anda dapat meretas ini jika Anda benar-benar tahu bahwa parameter opsi tidak terlihat seperti opsi lain yang valid, ya, tetapi orang bisa mengatakan bahwa ada alasan argumen opsional tidak didefinisikan dalam POSIX.bash
lexer dalam mengidentifikasi variabel. Mereka dalam banyak kasus tidak dibutuhkan dan fakta bahwa saya selalu menggunakannya hanyalah masalah gaya pengkodean pribadi. Bagi saya, lebih mudah (dan lebih cantik) untuk selalu menggunakannya daripada mengingat aturan parsing sehubungan dengan ambiguitas. Hampir sama mengapa seseorang akan menulisif (foo) { bar; }
alih-alihif (foo) bar;
dalam bahasa C-style (estetika dan / atau menghindari kesalahan konyol).Masalah dengan kode asli adalah:
h:
mengharapkan parameter di mana seharusnya tidak, jadi ubah menjadi adilh
(tanpa titik dua)-p any_string
, Anda perlu menambahkanp:
ke daftar argumenPada dasarnya
:
setelah opsi berarti membutuhkan argumen.Sintaks dasarnya
getopts
adalah (lihatman bash
:):dimana:
OPTSTRING
adalah string dengan daftar argumen yang diharapkan,h
- periksa opsi-h
tanpa parameter; memberikan kesalahan pada opsi yang tidak didukung;h:
- periksa opsi-h
dengan parameter; memberikan kesalahan pada opsi yang tidak didukung;abc
- cek untuk opsi-a
,-b
,-c
; memberikan kesalahan pada opsi yang tidak didukung;:abc
- cek untuk opsi-a
,-b
,-c
; membungkam kesalahan pada opsi yang tidak didukung;Catatan: Dengan kata lain, titik dua di depan opsi memungkinkan Anda menangani kesalahan dalam kode Anda. Variabel akan berisi
?
dalam kasus opsi yang tidak didukung,:
dalam kasus nilai yang hilang.OPTARG
- diatur ke nilai argumen saat ini,OPTERR
- menunjukkan apakah Bash akan menampilkan pesan kesalahan.Jadi kodenya bisa:
Contoh penggunaan:
Lihat: Tutorial getopts kecil di Bash Hackers Wiki
sumber
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Itu hanya menyumbang satu karakter spasi putih sebelum opsi huruf, menghapus # dari komentar dan menambahkan '-' sebelum opsi huruf membuatnya lebih jelas untuk perintah.:
hak sampai saya melihat catatan ini. Kita perlu menambahkan:
opsi ke mana kita mengharapkan argumen.Menggunakan
getopt
Mengapa getopt?
Untuk menguraikan argumen baris perintah yang diuraikan untuk menghindari kebingungan dan memperjelas opsi yang kami parsing sehingga pembaca perintah dapat memahami apa yang terjadi.
Apa itu getopt?
getopt
digunakan untuk memecah opsi (parse) di baris perintah untuk penguraian yang mudah dengan prosedur shell, dan untuk memeriksa opsi hukum. Ia menggunakangetopt(3)
rutinitas GNU untuk melakukan ini.getopt
dapat memiliki jenis opsi berikut.Catatan: Dalam dokumen ini, saat menjelaskan sintaks:
BAGAIMANA CARA MENGGUNAKAN
getopt
?Sintaks: Bentuk Pertama
Contoh:
Di sini h, v, t adalah opsi dan -h -v -t adalah bagaimana opsi harus diberikan dalam command-line.
Dalam param opsional, nilai tidak dapat memiliki pemisahan spasi dengan opsi. Jadi, dalam contoh "-t123", -t adalah opsi 123 adalah nilai.
Sintaks: Bentuk Kedua
Di sini setelah getopt dibagi menjadi lima bagian
Contohnya
Sintaks: Bentuk Ketiga
Di sini setelah getopt dibagi menjadi lima bagian
Contohnya
GETOPT_OPTIONS
getopt_options mengubah cara params baris perintah diuraikan.
Berikut adalah beberapa getopt_options
Opsi: -l atau --pilihan panjang
Misalnya,
--name=Karthik
adalah opsi panjang yang dikirim dalam baris perintah. Dalam getopt, penggunaan opsi panjang sepertiKarena nama: ditentukan, opsi harus mengandung nilai
Opsi: -a atau --alternatif
Contoh, alih-alih
--name=Karthik
Anda bisa menggunakan saja-name=Karthik
Contoh skrip lengkap dengan kode:
Menjalankan file skrip ini:
sumber
Contoh yang dikemas dengan
getopt
(distro saya memasukkannya ke dalam/usr/share/getopt/getopt-parse.bash
) sepertinya mencakup semua kasus Anda:sumber
Saya tahu bahwa ini sudah dijawab, tetapi untuk catatan dan untuk siapa pun dengan permintaan yang sama dengan saya, saya memutuskan untuk mengirim jawaban terkait ini. Kode dibanjiri dengan komentar untuk menjelaskan kode.
Jawaban yang diperbarui:
Simpan file sebagai
getopt.sh
:Maka Anda dapat menggunakannya seperti ini:
Jawaban lama:
Saya baru-baru ini perlu menggunakan pendekatan generik. Saya menemukan solusi ini:
Saya tidak menguji ini secara kasar, jadi saya bisa memiliki beberapa bug di sana.
sumber
getopts
fungsi, tambahkanlocal OPTIND OPTARG
ke fungsigetopts
Contoh 7 POSIX
Anda juga perlu memeriksa contoh dari standar: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
Dan kemudian kita bisa mencobanya:
Diuji di Ubuntu 17.10,
sh
adalah tanda hubung 0.5.8.sumber
"Getops" dan "getopt" sangat terbatas. Sementara "getopt" disarankan untuk tidak digunakan sama sekali, itu memang menawarkan opsi panjang. Sedangkan "getopts" hanya memungkinkan opsi karakter tunggal seperti "-a" "-b". Ada beberapa kelemahan lagi saat menggunakan salah satunya.
Jadi saya sudah menulis skrip kecil yang menggantikan "getopts" dan "getopt". Ini awal, mungkin banyak yang bisa diperbaiki.
Pembaruan 08-04-2020 : Saya telah menambahkan dukungan untuk tanda hubung mis. "--Package-name".
sumber