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.

3 Responses to “The 60 second getopts tutorial”

  1. sujoy Says:

    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.

  2. admin Says:

    I think what you want is:

    TABLE_NAME=”"
    while getopts "s:" table_name
    do
    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.

  3. rubin427 Says:

    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?

Leave a Reply

If Wordpress eats your comment (shell output, loops, ex..) email the text to me.