The 60 second getopts tutorial
October 15th, 2007
Processing command line arguments is a pain in any language. If done manually, parsing even a few options and option value pairs in BASH is a huge pain. As such and given the nature of shell scripts, they usually have exceedingly poor options processing. However, there is a solution. getopts is a BASH builtin which makes handling command line arguments like butter.
Here is how I have done so in this monitor cpu usage script. First I define all my option holding variables:
whatTowatch="" email="" startAtUid="-1" maxCpuUsage="-1" debug=""
The following while statement loops through all the options and sets them to the corresponding variable. getopts returns true while there are options to be processed. The argument string, here “hw:e:u:m:d”, specifies which options the script accepts. If the user specifies an option which is not in this string, it sets $optionName to ?. If the option is succeeded by a colon, the value immediately following the option is placed in the variable $OPTARG.
while getopts "hw:e:u:m:d" optionName; do case "$optionName" in h) printHelpAndExit 0;; d) debug="0";; w) whatTowatch="$OPTARG";; e) email="$OPTARG";; u) startAtUid="$OPTARG";; m) maxCpuUsage="$OPTARG";; [?]) printErrorHelpAndExit "$badOptionHelp";; esac done
All that’s left to do, is to make sure you have the correct option groups specified and your off and running.
outputCmd="mail -s 'CPU Abusers on ${HOSTNAME}' $email"
[[ "$whatTowatch" != "users" ]] && [[ "$whatTowatch" != "procs" ]] \
&& printErrorHelpAndExit "$watchHelp"
if [[ -z "$debug" ]]
then
( [[ "$maxCpuUsage" -ge 0 ]] && [[ "$maxCpuUsage" -le 100 ]] ) || \
printErrorHelpAndExit "$maxCpuHelp"
[[ "$startAtUid" -eq -1 ]] && [[ "$whatTowatch" == "users" ]] && \
printErrorHelpAndExit "$uidHelp"
[[ -z "$email" ]] && printErrorHelpAndExit "$emailHelp"
else
outputCmd=cat
fi
Here is what the script outputs when it encounters an unknown option:
# ./monitorCpuUsage.sh -x ./monitorCpuUsage.sh: illegal option -- x Option not recognised
The “./monitorCpuUsage.sh: illegal option — x” portion is printed by getopts. If you want to remain silent, just place a colon at the front of the argument string.


October 31st, 2007 at 1:21 pm
A simple but urgent query — I will be very grateful if you advise please. I am writing a script
xyz.ksh. It can be run in two modes:-
1) without any parameters.
2) with a tablename as xyz.ksh -s table_name
I am using
while getopts s:s table_name
do
case $table_name in
s) TABLE_NAME=$$OPTARG;;
done
The problem I am having is if someone is running by mistake “xyz.ksh -s” that is with the parameter but without the value I am being unable to throw an exception.
Please can you advise.
October 31st, 2007 at 2:02 pm
I think what you want is:
TABLE_NAME=”"
while getopts "s:" table_namedo
case $table_name in
s) TABLE_NAME=$$OPTARG;;
done
if [[ -z "$TABLE_NAME" ]]
then
# whatever you want with no parms
fi
That way if they set -s without a param, getopts will complain.
February 20th, 2008 at 2:10 pm
Over the past couple days, I’ve been experimenting with getopts trying to get arguments to a bash shell script given via command line. I came to the conclusion that getopts must not be used from inside a bash function, but rather from the main body of the bash script itself. Does this match other people’s experience?