Menggunakan getop untuk mengurai opsi setelah argumen non-opsi

10

Saya memiliki skrip bash seperti di bawah ini dalam file nepleaks_upd.sh, yang ingin saya jalankan sebagai ./nepleaks_upd.sh bootstrap --branch off. Tidak bisa mengambilnya --branch, tapi yang berhasil adalah ./nepleaks_upd.sh bootstrap -b off.

usage() { echo "Usage: $0 [prepare | up | down]  [-b <on/off>]" 1>&2; exit 1; }                                                                                                 

case "$1" in                                                                                           
               bootstrap)                                                                                  
                  while getopts ":b:" o; do                                                            
                   case "${o}" in                                                                      
                    b)                                                                                 
                        b=${OPTARG}                                                                    
                        if [ ${b} == "off" ]; then                                                      
                               echo "git clone https://github.com/iPrayag/dotfiles.git"  
                               ## logic                                                      
                        fi                                                                             
                        ;;                                                                             
                    *)                                                                                 
                        echo ${o}                                                                      
                        usage                                                                          
                        ;;                                                                             
                   esac                                                                                
                  done                                                                                 
                  shift $((OPTIND-1))                                                                  
                  echo "option1 = ${o}" 
                  echo "option2 = ${b}"                                                                      
                  if [ -z "${b}" ]; then                                                               
                         usage                                                                         
                  fi                                                                                   

                    ;;                                                                                 
                up)                                                                                         
                     echo "up"     
                     ##logic                                                                    
                     ;;                                                                                
                down)                                                                                  
                     echo "down" 
                     ##logic                                                                     
                    ;;                                                                                 
                *)                                                                                     
                    echo "Usage: $0 {up | down} dev"                                                
                    exit 1                                                                             
                    ;;                                                                                 
esac         

Tanpa dulu case .. in .... esac, itu berfungsi dengan baik. Dengan case ... in ... esac, itu memberikan opsi kosong untuk -b,

$ ./nepleaks_upd.sh bootstrap -b off
option1 = ?
option2 = 
Usage: ./nepleaks_upd.sh [bootstrap | up | down]  [-b <on/off>]
prayagupd
sumber
Tidakkah Anda harus memeriksa opsi sebelum menggunakan $1?
unxnut
@unxnut It menyanyikan samething bro
prayagupd
Apa yang Anda maksud dengan "Tanpa dulu case .. in .... esac, itu bekerja dengan baik"? Maksud Anda garis 5-25 diurai ./nepleaks_upd.sh -b offdengan benar? Mungkin Anda membutuhkan shift, jadi getoptsjangan tersedak " bootstrap".
Scott
@ Esc Ya, persis bagian itu berfungsi dengan baik.
prayagupd

Jawaban:

12

getoptsmulai parsing pada argumen pertama dan berhenti pada argumen non-opsi pertama. Itulah konvensi standar - beberapa utilitas GNU menerima opsi setelah argumen, tetapi hal yang normal adalah bahwa somecommand foo -bar qux, -bartidak diuraikan sebagai opsi.

Jika Anda ingin memulai opsi penguraian setelah itu bootstrap, Anda harus menunjukkannya. getoptsmenggunakan OPTINDvariabel untuk mengingat apa posisi itu. OPTINDdimulai dengan nilai 1. Untuk melewati argumen pertama, atur ke 2.

case "$1" in
   bootstrap)
      OPTIND=2
      while getopts ":b:" o; do
          

Atau, Anda bisa shiftmengajukan argumen yang sudah Anda proses.

subcommand=$1; shift
case "$subcommand" in
    bootstrap)
      while getopts ":b:" o; do
          
Gilles 'SANGAT berhenti menjadi jahat'
sumber