I have a script that has the following line:
while getopts "b:?1:?2:?g:r:n:t:?o:?" opt; do
how is this any different than:
while getopts "b:1:2:g:r:n:t:o:" opt; do
how is this any different than:
The first one is invalid. It's as different, as ?
will be most probably ignored by most getopts
implementations, but if getopts
decided to error on invalid optstring
that would be fine. From posix getopts:
optstring
A string containing the option characters recognized by the utility invoking getopts. [...]
The characters <question-mark> and <colon> shall not be used as option characters by an application. [...]
There are no other mentions of ?
, except for error handling. getopt
is a really simple utility, the ?
is returned by getopt
in case of parsing error.
The author most probably meant to do "optional option argument" - getopt
does not support such functionality (and if it would, I believe it would be denoted by two ::
like in GNU getopt
).
Looking at bash sources getopt.c, bash
uses simple strchr
to scan for the option in optstring
. Because there's ?
, it is interpreted as an option - it becomes impossible (or unnecessary hard) to differentiate between error and success, as ?
is returned in case of error.
$ OPTIND=0; set -- -'?' -g; while getopts "something:?does_not_matter" opt; do echo "$opt" "$OPTARG"; done
? # This is valid -? option
bash: option requires an argument -- g
? # This is error
$ OPTIND=0; set -- -'?'; while getopts "something:does_not_matter" opt; do echo "$opt" "$OPTARG"; done
bash: illegal option -- ?
? # This is error