Is it possible to implement a boolean cli option using getopts in bash? Basically I want to do one thing if -x
is specified and another if it is not.
On Unix-like operating systems, getopts is a builtin command of the Bash shell. It parses command options and arguments, such as those passed to a shell script.
Description. The getopts command is a Korn/POSIX Shell built-in command that retrieves options and option-arguments from a list of parameters. An option begins with a + (plus sign) or a - (minus sign) followed by a character. An option that does not begin with either a + or a - ends the OptionString.
$OPTIND is the number of options found by getopts . As pauljohn32 mentions in the comments, strictly speaking, OPTIND gives the position of the next command line argument. From the GNU Bash Reference Manual: getopts optstring name [args] getopts is used by shell scripts to parse positional parameters.
OPTIND and OPTARG are local to the shell script. If you want to export them, you must do so explicitly. If the script invoking getopts sets OPTIND to 1 , it can call getopts again with a new set of parameters, either the current positional parameters or new arg values.
Of course it is possible. @JonathanLeffler already pretty much gave the answer in the comments to the question, so all I'm going to do here is add an example of the implementation and a few niceties to consider:
#!/usr/bin/env bash
# Initialise option flag with a false value
OPT_X='false'
# Process all options supplied on the command line
while getopts ':x' 'OPTKEY'; do
case ${OPTKEY} in
'x')
# Update the value of the option x flag we defined above
OPT_X='true'
;;
'?')
echo "INVALID OPTION -- ${OPTARG}" >&2
exit 1
;;
':')
echo "MISSING ARGUMENT for option -- ${OPTARG}" >&2
exit 1
;;
*)
echo "UNIMPLEMENTED OPTION -- ${OPTKEY}" >&2
exit 1
;;
esac
done
# [optional] Remove all options processed by getopts.
shift $(( OPTIND - 1 ))
[[ "${1}" == "--" ]] && shift
# "do one thing if -x is specified and another if it is not"
if ${OPT_X}; then
echo "Option x was supplied on the command line"
else
echo "Option x was not supplied on the command line"
fi
A few notes about the above example:
true
and false
are used as option x indicators because both are valid UNIX commands. This makes the test for the option presence more readable, in my opinion.
getopts
is configured to run in silent error reporting mode because it suppressed default error messages and allows for a more precise error handling.
the example includes fragments of code for dealing with missing option arguments and post-getopts command line arguments. These are not part of the OP's question.
They are added for the sake of completeness as this code will be required in any reasonably complex script.
For more information about getopts
see Bash Hackers Wiki: Small getopts tutorial
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With