Saturday, May 17, 2014

Unix Shell Option Processing: getopts

1. Process parameter with loop and case
./script_1:
 #! /bin/bash  

 file=  
 verbose=  
 quiet=  
 while [ $# -ne 0 ]  
 do  
   case $1 in  
   -f) file=$2  
     echo "file:$file"  
     shift 2 #shift 2 parameters  
     ;;  
   -v) verbose=true  
     quiet=  
     echo "verbose flag is on"  
     shift  
     ;;  
   -q) quiet=true  
     verbose=  
     echo "quiet flag is on"  
     shift  
     ;;  
   *) echo unrecognized option  
     shift  
     ;;  
   esac  
 done  


terminal:
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -f text  
 file:text  
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -v  
 verbose flag is on  
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -q  
 quiet flag is on  
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 ff ff  
 unrecognized option  
 unrecognized option  


2. Process Parameters with getopt
./script_1:
 #! /bin/bash  

 file=  
 verbose=  
 quiet=  

 #":" right after 'f' means, for option f, user must supply the argument, otherwise  
 # system will complain  

 #OPTARG is the "argument" right after the "option", if we need to supply an argument here  

 #OPTIND is the index of next option waiting to be processed.  

 while getopts f:vq opt  
 do  
   echo $OPTARG  
   case $opt in  
   f) file=$OPTARG  
     echo "file:$file"  
     ;;  
   v) verbose=true  
     quiet=  
     echo "verbose flag is on"  
     ;;  
   q) quiet=true  
     verbose=  
     echo "quiet flag is on"  
     ;;  
   '?') echo "Input is invalid option"  
      ;;  
   esac  
   echo "index of next argument:"$OPTIND  
 done  

terminal:
Following command doesn't provide the argument for option -f, so getopts:
1) provide the error information on output 2) make $opt variable a questino mark, so we see output: "input is invalid option"
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -f  
 ./script_1: option requires an argument -- f  
 Input is invalid option  
 index of next argument:2  

Following command provides the filename "fff" as the argument, then getopts:
1) assign "fff" to $OPTARG
2) assign "f" to $opt, so we can see the output: "file:fff"
3) assign 3 to $OPTIND, since after "-f fff", the next option's index is 3
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -f fff  
 fff  
 file:fff  
 index of next argument:3  

Following command firstly process option "v", getopts:
1) assign empty space to $OPTARG, since there is no argument needed
2) assign "v" to $opt
3) assign 1 to $OPTIND, since the next option's index is still 1, because vq is at the same place

Then it process option "q", getopts is similar as above: 1) assign empty space to $OPTARG
2) assign "q" to $opt
3) assign 2 to $OPTIND, since the next option's index is indeed 2(option -f)

Finally it process option "f", getopts:
1) assign "fff" to $OPTARG
2) assign "f" to $opt
3) assign 4 to $OPTIND, since -f has one argument, which occupied one place
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -vq -f fff  

 verbose flag is on  
 index of next argument:1  

 quiet flag is on  
 index of next argument:2  
 fff  
 file:fff  
 index of next argument:4  

3. Make getopts silent
script_1:
 #! /bin/bash  

 file=  
 verbose=  
 quiet=  

 #":" at the first place of entire "option string" of getopts means:  
 #1) it won't print any error message  
 #2) assign '?' to $opt  
 #3) assign invalid option to $OPTARG  
 while getopts :f: opt  
 do  
   echo $OPTARG  
   case $opt in  
   f) file=$OPTARG  
     echo "file:$file"  
     ;;  
   '?') echo "Input is invalid option"  
      ;;  
   esac  
   echo "index of next argument:"$OPTIND  
 done  

terminal:
$OPTARG is assigned with 'd', which is the problematic option, and $opt is assigned with '?'
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -d  
 d  
 Input is invalid option  
 index of next argument:2  

===================================================
./script_1:
 #! /bin/bash  

 file=  
 verbose=  
 quiet=  

 #without ":" at the first place of entire option string of "getopts", it will:  
 #1) print out the error message  
 #2) assign "?" to $opt  
 #3) assign empty space to $OPTARG  
 while getopts f: opt  
 do  
   echo $OPTARG  
   case $opt in  
   f) file=$OPTARG  
     echo "file:$file"  
     ;;  
   '?') echo "Input is invalid option"  
      ;;  
   esac  
   echo "index of next argument:"$OPTIND  
 done  

terminal:
 aubinxia@aubinxia-fastdev:~/Desktop/xxdev$ ./script_1 -d  
 ./script_1: illegal option -- d  

 Input is invalid option  
 index of next argument:2  


No comments:

Post a Comment