10

I have a bash script as below in a file nepleaks_upd.sh, that I want to run as ./nepleaks_upd.sh bootstrap --branch off. Couldn't make it to take --branch , but what it works with is ./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         

Without first case .. in .... esac, it works fine. With case ... in ... esac, it gives blank option for -b,

$ ./nepleaks_upd.sh bootstrap -b off
option1 = ?
option2 = 
Usage: ./nepleaks_upd.sh [bootstrap | up | down]  [-b <on/off>]
  • Shouldn't you check for options before you use $1? – unxnut Jul 4 '14 at 21:28
  • @unxnut It sings samething bro – prayagupd Jul 4 '14 at 21:47
  • What do you mean by “Without first case .. in .... esac, it works fine”? Do you mean that lines 5-25 parse ./nepleaks_upd.sh -b off correctly? Maybe you need a shift, so getopts doesn’t choke on the “bootstrap”. – Scott Jul 4 '14 at 22:57
  • @Scott Yes, exactly that part works fine. – prayagupd Jul 5 '14 at 8:52
12

getopts starts parsing at the first argument and stops at the first non-option arguments. That's the standard convention — some GNU utilities accept options after arguments, but the normal thing is that in somecommand foo -bar qux, -bar is not parsed as an option.

If you want to start parsing options after bootstrap, you need to indicate that. getopts uses the OPTIND variable to remember what position it's at. OPTIND starts out with the value 1. To skip the first argument, set it to 2.

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

Alternatively, you could shift the arguments that you've already processed.

subcommand=$1; shift
case "$subcommand" in
    bootstrap)
      while getopts ":b:" o; do
          …

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.