Apakah ada beberapa alat bawaan yang akan mengenali -x
dan --xxxx
sebagai saklar, dan bukan argumen, atau apakah Anda harus melalui semua variabel input, menguji tanda hubung, dan kemudian menguraikan argumen setelahnya?
Apakah ada beberapa alat bawaan yang akan mengenali -x
dan --xxxx
sebagai saklar, dan bukan argumen, atau apakah Anda harus melalui semua variabel input, menguji tanda hubung, dan kemudian menguraikan argumen setelahnya?
Jawaban:
Gunakan getopts
.
Ini cukup portabel seperti pada spec POSIX. Sayangnya itu tidak mendukung opsi lama.
Lihat juga getopts
tutorial ini dari wiki bash-hacker dan pertanyaan ini dari stackoverflow.
Jika Anda hanya memerlukan opsi pendek, pola penggunaan umum untuk getopts
(menggunakan pelaporan kesalahan tidak diam) adalah:
# process arguments "$1", "$2", ... (i.e. "$@")
while getopts "ab:" opt; do
case $opt in
a) aflag=true ;; # Handle -a
b) barg=$OPTARG ;; # Handle -b argument
\?) ;; # Handle error: unknown option or missing required argument.
esac
done
while getopts "ab:" opt
?
:
setelah yang menandakan itu membutuhkan argumen. A :
sebagai karakter pertama berarti untuk menekan pesan kesalahan.
Saya menganggap Anda menggunakan bash atau serupa. Sebuah contoh:
all=false
long=false
while getopts ":hal" option; do
case $option in
h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;;
a) all=true ;;
l) long=true ;;
?) echo "error: option -$OPTARG is not implemented"; exit ;;
esac
done
# remove the options from the positional parameters
shift $(( OPTIND - 1 ))
ls_opts=()
$all && ls_opts+=( -a )
$long && ls_opts+=( -l )
# now, do it
ls "${ls_opts[@]}" "$@"
+=
dengan array. Tidak tahu kamu bisa melakukan itu. Bagus!
Anda harus menulis siklus untuk mem-parsing parameter. Memang Anda bisa menggunakan getopts
perintah untuk melakukannya dengan mudah.
Ini adalah contoh sederhana dari getopts
halaman manual:
aflag=
bflag=
while getopts ab: name
do
case $name in
a) aflag=1;;
b) bflag=1
bval="$OPTARG";;
?) printf "Usage: %s: [-a] [-b value] args\n" $0
exit 2;;
esac
done
if [ ! -z "$aflag" ]; then
printf "Option -a specified\n"
fi
if [ ! -z "$bflag" ]; then
printf 'Option -b "%s" specified\n' "$bval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
Saya menulis skrip baru-baru ini untuk pekerjaan yang fleksibel dan memungkinkan untuk beberapa jenis switch dalam urutan apa pun. Saya tidak dapat mengungkapkan skrip lengkap untuk alasan hukum yang jelas (belum lagi saya tidak memilikinya bersama saya saat ini), tetapi inilah dagingnya .. Anda dapat memasukkannya ke dalam subrutin dan menyebutnya di akhir naskah Anda:
options () {
if [ -n "$1" ]; then # test if any arguments passed - $1 will always exist
while (( "$#" )); do # process ALL arguments
if [ "$1" = ^-t$ ]; then # -t short for "test"
# do something here THEN shift the argument
# shift removes it from $@ and reduces $# by
# one if you supply no argument
shift
# we can also process multiple arguments at once
elif [[ "$1" =~ ^--test=[:alnum:]{1,8}$ ]] && [[ "$2" =~ ^-t2$ ]] && [[ -n "$3" ]]; then # check for 3 arguments
# do something more then remove them ALL from the arg list
shift 3
else
echo "No matching arguments!"
echo "Usage: [script options list here]"
fi
done
else
echo "Usage: [script options list here]"
exit 0
fi
}
options "$@" # run options and loop through/process ALL arguments
Saya sarankan membatasi skrip bash Anda menjadi kurang dari 400 baris / 15k karakter; skrip saya yang tadi tumbuh melebihi ukuran ini dan menjadi sangat sulit untuk dikerjakan. Saya mulai menulis ulang di Perl, yang jauh lebih cocok untuk tugas itu. Ingatlah hal itu saat Anda mengerjakan skrip Anda di bash. Bash bagus untuk skrip dan oneliner kecil, tetapi ada yang lebih kompleks dan Anda lebih baik menulisnya di Perl.
Catatan, saya belum menguji di atas, jadi mungkin tidak berhasil, tetapi Anda mendapatkan ide umum dari itu.
options
pada akhirnya tidak benar, itu akan kembali -bash: syntax error near unexpected token $@
. Sebut saja sebagai options "$@"
.
while
kondisi seharusnya tidak (($#))
bukan?
$#
? Sunting: Anda benar. Memperbaikinya kewhile (( "$#" ))
getopt
harus selalu diverifikasi sebagai GNU getopt sebelum Anda menggunakannya, tetapi Anda tidak boleh menggunakannya karenagetopts
lebih portabel (dan umumnya lebih baik). Jika Anda lakukan perlu menyebutnya untuk beberapa alasan, menyebutnya dengan cara GNU khusus, dan memastikan bahwaGETOPT_COMPATIBLE
tidak dalam lingkungan.