Let's say I'm running getopts in a Bash script with the option string ":a:b" and I provide the following command line parameters:
./script.sh -a foo bar -b bar zappo
The instance of "foo" is an expected argument for the option a and the option b has no expected argument. However, both instances of "bar" and the instance of "zappo" are unacceptable to getopts. After running getopts, how can I echo a variable containing a list of all of the unacceptable arguments? How could I produce the list "bar bar zappo"? Thanks!
Here's some code for your convenience:
#!/bin.bash
option_string=":a:b"
unexpected_parameters=""
OPTIND=1
while getopts "${option_string}" options; do
case ${options} in
a)
echo "-a triggered with parameter ${OPTARG}" >&2 # output to STDERR
;;
b)
echo "-b triggered" >&2 # output to STDERR
;;
\?)
echo "invalid option: -${OPTARG}" >&2 # output to STDERR
;;
esac
#<insert code magic... unexpected_parameters="${unexpected_parameters} "$(MAGIC)"">
done
echo "unexpected parameters: ${unexpected_parameters}"
getoptsstops processing at the first non-option argument. That's Posix-style argument processing. In Posix-style argument processing, given the commandutilitywill not interpret-bas a command-line flag. If-atakes an argument, thenbarwill be the first positional argument, and then there will be three more positional arguments,-b,bar, andzappo.GNU extends this syntax by permuting command-line arguments so that flag options can be anywhere in the command-line. However, if you set the environment variable
POSIXLY_CORRECT, then GNU utilities will (mostly) behave like normal Posix utilities. The GNU version of the Posix C library functiongetopt(3)(andgetopt_long(3)) use GNU syntax by default, and also react appropriate to thePOSIXLY_CORRECTenvironment variable.However, the bash
getoptsbuiltin is strictly Posix-style. So in your case, withgetopts ":a:b", your loop will only be executed once, for flagawith argumentfoo. Whengetoptsterminates,OPTINDis set the the index of the first unconsumed command-line argument, in this case3(bar).If you want to use
getoptswith GNU-style option handling, you have to do the permuting yourself. For example, you could do something like this:Alternatively, you can use the GNU implementation of
getopt(1), which will do all that for you, at the cost of a slightly more annoying interface. (At least, I find it annoying, but YMMV.)