Trapping getopt invalid options Trapping getopt invalid options bash bash

Trapping getopt invalid options


This sort of style works for me:

params="$(getopt -o d:h -l diff:,help --name "$cmdname" -- "$@")"if [ $? -ne 0 ]then    usagefieval set -- "$params"unset paramswhile truedo    case $1 in        -d|--diff)            diff_exec=(${2-})            shift 2            ;;        -h|--help)            usage            exit            ;;        --)            shift            break            ;;        *)            usage            ;;    esacdone


This is not the most robust solution, but it's reasonable; it relies on the following:

  • The error message that getopt prints is prefixed with "getopt: "
  • The assumption is that it's acceptable to pass through a cleaned-up version of getopt's error message, augmented with custom information.

Code snippet:

# Invoke getopt; suppress its stderr initially.args=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>/dev/null)if [[ $? -ne 0 ]]; then # getopt reported failure    # Rerun the same getopt command so we can capture stderr output *only* this time.    # Inefficient (and a potential maintenance headache, if literals were involved), but this will only execute in case of invalid input.    # Alternatively, redirect the first getopt invocation's stderr output to a temp. file and read it here.    errmsg=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>&1 1>&-)    # Strip getopt's prefix and augment with custom information.    echo -e "${errmsg#getopt: }\nTry './cmd.sh --help for more information." 1>&2    exit 1fi


Do you have to use getopt at all? If you just use

while [ $# -gt 0 ]; do  case "$1" in    -d|--diff)       diff_exec=(${2-})       shift       ;;    -h|--help)       usage       exit       ;;     --)       break       ;;     *)       usage       ;;    esac    shiftdone

Then you own code is doing the checking.