Parsing Arguments with Your Own Error Messages

Problem

You are using getopts to parse your options for your shell script. But you don’t like the error messages that it writes when it encounters bad input. Can you still use getopts but write your own error handling?

Solution

If you just want getopts to be quiet and not report any errors at all, just assign $OPTERR=0 before you begin parsing. But if you want getopts to give you more information without the error messages, then just begin the option list with a colon. (The v--- in the comments below is meant to be an arrow pointing to a particular place in the line below it, to show that special colon.)

#!/usr/bin/env bash
# cookbook filename: getopts_custom
#
# using getopts - with custom error messages
#
aflag=
bflag=
# since we don't want getopts to generate error
# messages, but want this script to issue its
# own messages, we will put, in the option list, a
# leading ':' v---here to silence getopts.
while getopts :ab: FOUND
do
    case $FOUND in
        a)  aflag=1
            ;;
        b)  bflag=1
            bval="$OPTARG"
            ;;
        :) printf "argument missing from -%s option
" $OPTARG
            printf "Usage: %s: [-a] [-b value] args
" $(basename $0)
            exit 2
            ;;
        ?) printf "unknown option: -%s
" $OPTARG
            printf "Usage: %s: [-a] [-b value] args
" $(basename $0)
            exit 2
            ;;
        esac >&2
    done
shift $(($OPTIND - 1))

if [ "$aflag" ]
then
    printf "Option -a specified
"
fi
if [ "$bflag" ]
then
    printf 'Option -b "%s" specified
' "$bval"
fi
printf "Remaining arguments are: %s
" "$*"

Discussion

The script is very much the same as the recipe Parsing Arguments for Your Shell Script. See that discussion for more background. One difference here is that getopts may now return a colon. It does so when an option is missing (e.g., you invoke the script with -b but without an argument for it). In that case, it puts the option letter into $OPTARG so that you know what option it was that was missing its argument.

Similarly, if an unsupported option is given (e.g., if you tried -d when invoking our example) getopts returns a question mark as the value for $FOUND, and puts the letter (the d in this case) into $OPTARG so that it can be used in your error messages.

We put a backslash in front of both the colon and the question mark to indicate that these are literals and not any special patterns or shell syntax. While not necessary for the colon, it looks better to have the parallel construction with the two punctuations both being escaped.

We added an I/O redirection on the esac (the end of the case statement), so that all output from the various printf statements will be redirected to standard error. This is in keeping with the purpose of standard error and is just easier to put it here than remembering to put it on each printf individually.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.82.21