Difference between revisions of "Bash/Parsing command line arguments using getopts"

From ProgrammingExamples
Jump to: navigation, search
(Add example of handling command line arguments)
 
Line 1: Line 1:
This is an example of looping over the command line parameters, handling flags and arguments. To do it right, I ended up showing several other things too. The critical bits are
+
Handling command line arguments can be done many ways, but few will be as elegant and streamlined as the built-in shell command called getopts. Note: getopt is the older version and should not be used as it is far less robust.
* looping by checking the number of remaining args '''$#'''
+
 
* using '''case / esac''', case tags '''xxx)''', '''shift''' and ''';;'''
+
Getopts shifts the data and sets an exit status of false when there is nothing left to do. Because of this behavior, getopts works well in a while loop as follows:
* using '''cat <<EOM''' ... '''EOM''' to provide a multi-line message
+
 
 +
<syntaxhighlight lang="bash">
 +
while getopts ...; do
 +
  ...
 +
done
 +
</syntaxhighlight>
 +
 
 +
Often used in conjunction with getopts is the following conditional statement to force a certain number of arguments to be supplied:
 +
 
 +
<syntaxhighlight lang="bash">
 +
#Check to see if the right number of arguments were supplied
 +
if [ $# -lt 1 ] ; then
 +
  ...
 +
fi
 +
</syntaxhighlight>
 +
 
 +
 
 +
The following script shows the usage of getopts. Getopts can't handle long options and will stop processing arguments when it hits the "--" argument (end of options). To specify an argument, the first letter of the word to be used as a switch is placed after the getopts command with an optional ":" if it also requires an additional parameter. An example program can be seen below.
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
#!/bin/bash
 
#!/bin/bash
  
globalVariableStrings=''  # by default, bash variables are strings
+
#Set a default value for the $cell variable
declare -i globalVariableInt=0 # but if you know it's an int, declare it so
+
cell="test"
while [[ $# -gt 0 ]] ; do # $# is the count of command line args
+
 
  case $1 in              # $1 is the first (remaining) arg.  
+
#Check to see if at least one argument was specified
  # case tags can be simple regular expressions. cat <<EOM cats everything up to a solo EOM on a line
+
if [ $# -lt 1 ] ; then
  -h|--h*)cat <<EOM     
+
  echo "You must specify at least 1 argument."
Usage: $(basename $0) [flags] [arguments]
+
  exit 1
-h/--help: Show this message and exit
+
fi
-i value /--int=value: handle an integer flag. Last one wins
+
 
<argument> handle a non-flag argument. Each seen is appended
+
#Process the arguments
EOM
+
while getopts c:hi: opt
  exit 0 ;;              # exit 0 flags 'success'. ;; shows end of a case statement
+
do
  -i) shift;              # shift removes the first arg (-i here)
+
  case "$opt" in
      globalVariableInt=$1  # set the integer value
+
      c) cell=$OPTARG;;
      shift ;;           # remove the integer value and drop from the case block
+
      h) usage;;
  --int=*)  
+
      n) name=$OPTARG;;
      globalVariableInt=$(echo $1|cut -f2 -d=) # -f: Which field; -d: what delimiter
+
      \?) usage;;
      shift ;;          # as always
+
  esac
  *) globalVariableStrings="$globalVariableStrings $1" # append argument
+
    shift ;;             # as always
+
  esac
+
done
+
echo "The integer is $globalVariableInt"
+
for s in $globalVariableStrings ; do
+
  echo "You entered argument '$s'"
+
 
done
 
done
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
 +
Example usages:
 +
 +
<syntaxhighlight lang="bash">
 +
getopts_example.sh -c test1 -n test2
 +
getopts_example.sh -c test3
 +
getopts_example.sh -h
 +
getopts_example.sh -a
 +
</syntaxhighlight>
 +
 +
 +
Example 1 would assign "test1" to the $cell variable and "test2" to the $name variable.
 +
 +
Example 2 would assign "test3" to the $cell variable and $name would not exist.
 +
 +
Example 3 would call the usage function.
 +
 +
Example 4 would cause getopts to display an error to stderr and then exit after calling the usage function.

Revision as of 21:56, 4 October 2011

Handling command line arguments can be done many ways, but few will be as elegant and streamlined as the built-in shell command called getopts. Note: getopt is the older version and should not be used as it is far less robust.

Getopts shifts the data and sets an exit status of false when there is nothing left to do. Because of this behavior, getopts works well in a while loop as follows:

while getopts ...; do
  ...
done

Often used in conjunction with getopts is the following conditional statement to force a certain number of arguments to be supplied:

#Check to see if the right number of arguments were supplied
if [ $# -lt 1 ] ; then
  ...
fi


The following script shows the usage of getopts. Getopts can't handle long options and will stop processing arguments when it hits the "--" argument (end of options). To specify an argument, the first letter of the word to be used as a switch is placed after the getopts command with an optional ":" if it also requires an additional parameter. An example program can be seen below.

#!/bin/bash
 
#Set a default value for the $cell variable
cell="test"
 
#Check to see if at least one argument was specified
if [ $# -lt 1 ] ; then
   echo "You must specify at least 1 argument."
   exit 1
fi
 
#Process the arguments
while getopts c:hi: opt
do
   case "$opt" in
      c) cell=$OPTARG;;
      h) usage;;
      n) name=$OPTARG;;
      \?) usage;;
   esac
done


Example usages:

getopts_example.sh -c test1 -n test2
getopts_example.sh -c test3
getopts_example.sh -h
getopts_example.sh -a


Example 1 would assign "test1" to the $cell variable and "test2" to the $name variable.

Example 2 would assign "test3" to the $cell variable and $name would not exist.

Example 3 would call the usage function.

Example 4 would cause getopts to display an error to stderr and then exit after calling the usage function.