Trapping getopt invalid options

Tom Auger picture Tom Auger · Oct 5, 2011 · Viewed 14.2k times · Source

I'm using getopt (not getops) to provide the ability for my bash script to process options and switches (both long --option and short -o forms).

I'd like to be able to trap invalid options and handle them, typically echoing out that the user should try cmd --help and then exiting the script.

Thing is, the invalid options are being caught by getopt, which is itself outputting a message such as "getopt: invalid option -- 'x'"

Here's the pattern I'm using to set my getopt parameters:

set -- $(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@")

where both $LONG_OPTIONS and $SHORT_OPTIONS are a comma-delimited list of options.

Here's how I handle processing the options:

 while [ $# -gt 0 ]
    do
        case "$1" in
            -h|--help)
                cat <<END_HELP_OUTPUT

    Help
    ----

    Usage: ./cmd.sh 

    END_HELP_OUTPUT

                shift;
                exit
                ;;
            --opt1)
                FLAG1=true
                shift
                ;;
            --opt2)
                FLAG2=true
                shift
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Option $1 is not a valid option."
                echo "Try './cmd.sh --help for more information."
                shift
                exit
                ;;
        esac
    done

getopt -q will suppress the output, but my trapping scheme within the case statement still fails to do what I expect. Instead, the program just executes, despite the invalid arguments.

Answer

l0b0 picture l0b0 · Oct 6, 2011

This sort of style works for me:

params="$(getopt -o d:h -l diff:,help --name "$cmdname" -- "$@")"

if [ $? -ne 0 ]
then
    usage
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -d|--diff)
            diff_exec=(${2-})
            shift 2
            ;;
        -h|--help)
            usage
            exit
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done