Używanie getopts do analizowania opcji po argumencie innym niż opcja


10

Mam skrypt bash jak poniżej w pliku nepleaks_upd.sh, który chcę uruchomić jako ./nepleaks_upd.sh bootstrap --branch off. Nie można tego zrobić --branch, ale działa z tym ./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         

Bez pierwszego case .. in .... esacdziała dobrze. Z case ... in ... esacdaje pustą opcję dla -b,

$ ./nepleaks_upd.sh bootstrap -b off
option1 = ?
option2 = 
Usage: ./nepleaks_upd.sh [bootstrap | up | down]  [-b <on/off>]

Czy nie powinieneś sprawdzić opcji przed użyciem $1?
unxnut

@unxnut Śpiewa samething bracie
prayagupd

Co rozumiesz przez „bez najpierw case .. in .... esacdziała dobrze”? Czy masz na myśli, że wiersze 5-25 analizują ./nepleaks_upd.sh -b offpoprawnie? Może potrzebujesz shift, więc getoptsnie dusi się na „ bootstrap”.
Scott

@ Scott Tak, dokładnie ta część działa dobrze.
prayagupd,

Odpowiedzi:


12

getoptsrozpoczyna parsowanie od pierwszego argumentu i zatrzymuje się od pierwszych argumentów nie będących opcjami. To standardowa konwencja - niektóre narzędzia GNU akceptują opcje po argumentach, ale normalną rzeczą jest to, że w somecommand foo -bar qux, -barnie jest analizowane jako opcja.

Jeśli chcesz później rozpocząć analizowanie opcji bootstrap, musisz to zaznaczyć. getoptsużywa OPTINDzmiennej, aby zapamiętać, na jakiej pozycji się znajduje. OPTINDzaczyna się od wartości 1. Aby pominąć pierwszy argument, ustaw go na 2.

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

Alternatywnie możesz użyć shiftargumentów, które już przetworzyłeś.

subcommand=$1; shift
case "$subcommand" in
    bootstrap)
      while getopts ":b:" o; do
          
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.