Using getopts to parse options after a non-option argument

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>]

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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
          …


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x