Saya menggunakan getopts untuk mem-parsing argumen dalam skrip bash sebagai
while getopts ":hd:" opt; do
case $opt in
d ) echo "directory = $OPTARG"; mydir="$OPTARG"; shift $((OPTIND-1)); OPTIND=1 ;;
h ) helptext
graceful_exit ;;
* ) usage
clean_up
exit 1
esac
done
exeparams="$*"
exeparams
akan menyimpan opsi / argumen yang tidak diparsing. Karena saya ingin menggunakan exeparams untuk menyimpan opsi agar suatu perintah dapat dieksekusi di dalam skrip (yang dapat tumpang tindih dengan opsi skrip sendiri), saya ingin menggunakan - untuk mengakhiri opsi yang diteruskan ke skrip. Jika saya lulus mis
myscript -d myscriptparam -- -d internalparam
exeparams
akan memegang
-- -d internalparam
Saya sekarang ingin menghapus yang memimpin --
untuk meneruskan argumen ini ke perintah internal. Apakah ada cara yang elegan untuk melakukan ini atau bisakah saya mendapatkan string yang hanya memegang sisanya tanpa --
dari getop?
shift; OPTIND=1
di dalamgetopts
lingkaran mungkin bukan cara terbaik untuk melakukannya. Ini hanya berfungsi dalam kasus Anda karena Anda hanya memiliki 2 opsi dan di semua yang lain Anda hanya keluar dari skrip. Kalau tidak, Anda akan membutuhkanshift; OPTIND=1
di setiap opsi, yang berarti kode duplikat (praktik buruk). Lakukanshift $((OPTIND - 1))
segera setelah akhir loop - ini adalah cara yang paling konvensional dan mungkin yang paling efisien juga.Jawaban:
Bagaimana tentang:
Catatan, Anda harus menggunakan array untuk menyimpan parameter. Itu akan menangani dengan baik argumen yang berisi spasi putih. Dereferensi array dengan
"${exeparams[@]}"
sumber
--
, yaituscript foo -- bar
akan diteruskanfoo -- bar
ke program eksternal. Jawaban saya tidak membuat asumsi itu karena tidak secara eksplisit dinyatakan dalam pertanyaan.-- -d internalparams
. Bagaimanapun, jawaban saya cukup umum untuk menangani kedua kasus tersebut.Gunakan built-in
shift
. Pertama, lakukan hal yang normalgetopts
untuk skrip Anda. Setelah loop itu selesai,akan menggeser semua opsi yang sudah diproses.
Dari sana, Anda harus menyelesaikan pemrosesan argumen non-opsi, jika ada, ke bagian pertama skrip (sebelum
--
). Setelah Anda menemukan--
, geser keluar sampai hanya bagian terakhir yang tersisa (-d internalparam
bagian yang datang setelah--
). Salah satu cara untuk melakukan ini (menggunakanbash
sintaks):Akhirnya, hanya set kedua opsi / argumen yang tersisa, yang bisa Anda sampaikan. Apakah TIDAK menggunakan
$*
untuk melewati parameter yang tersisa untuk perintah lain. Gunakan"$@"
sebagai gantinya, yang mempertahankan pemisahan kata asli.sumber
--
?