16

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>]
4
  • Shouldn't you check for options before you use $1?
    – unxnut
    Jul 4, 2014 at 21:28
  • @unxnut It sings samething bro Jul 4, 2014 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”. Jul 4, 2014 at 22:57
  • @Scott Yes, exactly that part works fine. Jul 5, 2014 at 8:52

1 Answer 1

18

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
          …

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .