Handling positional and non-positional command line arguments from a shell script

When you want to use non-positional command line arguments together with positional you may use getopts to parse non-positional arguments and than use $OPTIND environment variable set by getopts to access positional arguments.

Of course positional arguments should follow non-positional ones. Let’s assume you plan to have following syntax:

script.sh [options] ARG1 ARG2

At first you have to parse non-positional arguments which will be options in this case with getopts:

while getopts "h:u:p:d:" flag; do
case "$flag" in
    h) HOSTNAME=$OPTARG;;
    u) USERNAME=$OPTARG;;
    p) PASSWORD=$OPTARG;;
    d) DATABASE=$OPTARG;;
esac
done

Than you may want to ensure that required positional arguments were passed:

if [ $(( $# - $OPTIND )) -lt 1 ]; then
    echo "Usage: `basename` [options] ARG1 ARG2"
    exit 1
fi

Later you can access positional arguments using array expansion ${@:START:1}:

ARG1=${@:$OPTIND:1}
ARG2=${@:$OPTIND+1:1}

Leave a Reply