Have you ever passed several parameters to a command like this: ls -lah
, and thought “I wish my bash scripts could parse command line parameters like that.” Allow me to introduce you to a bash function named getopts. Reader, meet getopts; getopts, meet reader.
The function getopts
iterates through all command line parameters, evaluating if they match an expected parameter set. It takes two arguments: a string representing allowed parameters and a variable name to use while iterating through arguments. Here’s an example that should explain things:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#!/bin/bash # #file name: getopts.sh # #Sample script that takes two parameters, a, b, c, and v using getopts. #Parameters a and c are simple on/off switches #The b parameter takes a value. #The v parameter will be used to keep track of a verbosity level; # more '-v's results in a higher verbosity level # usage=$( cat <<EOF $0 [OPTION] -a set the "a" flag -b VALUE set "b" argument to VALUE -c set the "c" flag -v increase verbosity (-v = verbosity level 1; -vv = verbosity level 2; ...) EOF ) #define default values AFLAG_DEFAULT="off" BFLAG_DEFAULT="" CFLAG_DEFAULT="off" verbosity=0 #getopts returns success if an option is found and failure otherwise #so looping on it results in parsing all command line parameters #ab:cv is how we represent the flags to be accepted while getopts "ab:cv" OPTION; do case "$OPTION" in a) AFLAG="on" ;; b) #the colon after b in the args string above signifies that # b should be accompanied with a user-defined value. #that value will be stored in the OPTARG environment variable BFLAG="$OPTARG" ;; c) CFLAG="on" ;; v) #each -v should increase verbosity level verbosity=$(($verbosity+1)) ;; *) echo "unrecognized option" echo "$usage" ;; esac done #setting default values: #this command will set VARIABLE to DEFAULT_VALUE if it is currently # undefined, then return VARIABLE #${VARIABLE=DEFAULT_VALUE} #use a : to prevent bash from attempting to execute the value of # VARIABLE when it is returned : ${AFLAG=$AFLAG_DEFAULT} : ${BFLAG=$BFLAG_DEFAULT} : ${CFLAG=$CFLAG_DEFAULT} #verbosity doesn't need a default value; it was initialized to 0 above. #show the values as read in by the flags cat <<EOF a: $AFLAG b: $BFLAG c: $CFLAG verbosity: $verbosity EOF |
Here are some sample runs to demonstrate the flexibility in how arguments can be passed:
Everything as a separate flag
1 2 3 4 5 |
$ ./getopts.sh -a -b aardvark -c -v -v -v a: on b: aardvark c: on verbosity: 3 |
All flags grouped together for the same effect (order does not matter)
1 2 3 4 5 |
$ ./getopts.sh -vvvacb aardvark a: on b: aardvark c: on verbosity: 3 |
Some flags grouped, some separated; default values used for missing arguments
1 2 3 4 5 |
$ ./getopts.sh -av -b aardvark a: on b: aardvark c: off verbosity: 1 |
or…
for arg in $@
do
export temp=`echo $arg | perl -pe ‘s/^(-.*a.*)$/found/g’`
if [ $temp == “found” ]
then
#do Whatever for argument a
fi
done
making it more complex to match the functionality you have here would not by very difficult at all. why restrict yourself purely to bash?
This is by far the easiest to understand example of using getopts with bash out there! THX
[…] Parsing Arguments in Bash (getopts) | Atomic SpinParsing Arguments in Bash (getopts). By Andrew Bellenir | Published: March 30, 2011. Have you ever passed several parameters to a command like this: ls -lah … […]