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?
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 " "$*"
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.
3.144.82.21