Here is a trick I have found to use arguments with optional parameters with getopts.
The way to manage the case where the optional parameter is inside the command is given by Jan Schampera in is reply on bash-hackers.org :
if [[ $OPTARG = -* ]]; then
((OPTIND--))
continue
fi
(see : http://wiki.bash-hackers.org/howto/getopts_tutorial deep in the page)
But it does not manage the case where the option is given at the end of the command.
In that case, that is considered wrong because no parameter is given, getopts
set the opt
variable to ':' (colon) and OPTARG
to the fault option value.
So we have to manage the ':' case, with a case $OPTARG
.
Let us say we write a script having three options :
a
: without parameter
b
: with a required parameter
v
: to set the verbosity with a value from 0
to 2
. The default value is 0
and a preset value is used when the script is called with -v
without parameter or with a bad value.
Here is the code :
#!/bin/bash
VERBOSITY=0 # default verbosity set to 0
PRESET_VERBOSITY=1 # preset verbosity when asked
while getopts :ab:v: opt; do
case $opt in
a)
echo "manage option a"
;;
b)
echo "manage option b with value '$OPTARG'"
;;
v)
if [[ $OPTARG = -* ]]; then # Jan Schampera reply
echo "set verbosity to PRESET (no value given, not last position)"
VERBOSITY=$PRESET_VERBOSITY
((OPTIND--))
continue
fi
if [[ "$OPTARG" =~ ^[0-2]$ ]]; then
echo "set verbosity to $OPTARG (good value given)"
VERBOSITY=$OPTARG
else
echo "set verbosity to PRESET (bad value given)"
VERBOSITY=$PRESET_VERBOSITY
fi
;;
:)
case $OPTARG in
v)
echo "set verbosity to PRESET (no value given, last option)"
VERBOSITY=$PRESET_VERBOSITY
;;
esac
;;
\?)
echo "WTF!"
;;
esac
done
echo "**verbosity is set to $VERBOSITY**"