Parsing Command Line Options in Shell Scripts

In programs written in C, command line argument parsing has always been done using the getopt(3) library function. This function has set the standards Linux/Unix users have come to expect from command line interfaces. Fortunately, there's a getopt(3) equivalent for almost every programming language and the shell is no exception.

The getopts command available in all POSIX-compliant Bourne shell derivates (like bash, dash, or ksh) provides convenient command line parsing capabilities. It is a builtin accepting POSIX-style argument lists (as opposed to GNU-style, which is a bit more fancy) and should not be confused with the getopt utility.

For my shell scripts, I use the following template to implement command line parsing:

#! /bin/sh

USAGE="Usage: `basename $0` [-hv] [-o arg] args"

# Parse command line options.
while getopts hvo: OPT; do
    case "$OPT" in
        h)
            echo $USAGE
            exit 0
            ;;
        v)
            echo "`basename $0` version 0.1"
            exit 0
            ;;
        o)
            OUTPUT_FILE=$OPTARG
            ;;
        \?)
            # getopts issues an error message
            echo $USAGE >&2
            exit 1
            ;;
    esac
done

# Remove the switches we parsed above.
shift `expr $OPTIND - 1`

# We want at least one non-option argument.
# Remove this block if you don't need it.
if [ $# -eq 0 ]; then
    echo $USAGE >&2
    exit 1
fi

# Access additional arguments as usual through
# variables $@, $*, $1, $2, etc. or using this loop:
for PARAM; do
    echo $PARAM
done

# EOF

It is easy to add more command line switches. If you want to add an -x switch requiring an argument (-x arg) and a y flag without an argument, you would have to change the getopts call to getopts hvo:x:y OPT and add two case labels to the loop. Note that the colon indicates that an argument is required for a flag.

social