Arguments and options for your Bash scripts
Write Bash scripts with options and arguments and use getopts for parsing
Published on
getopts
parses command-line arguments passed to a script. It is defined in POSIX, is a Bash builtin and works with other shells too.
It is usable for simple scripts but:
- for a more flexible implementation see Loop through arguments and options in your Bash scripts
- the practical implementation that I use now is without
getopts
and is presented in Bash scripting article
getopts
allow only single-letter options and performs option splitting (-hv will be processed as -h -v).
Short note about positional parameters
$#
is a special variable that contains the number of arguments passed to the script.- Positional parameter N may be referenced as
${N}
, or as$N
whenN
consists of a single digit.$0
is reserved and expands to the name of the shell or shell script. - Use
"$@"
(keep the quotes) to get all passed arguments as separate words.
See Shell Parameters for more information.
Options
To get the options passed to the script use getopts
with an option_string
.
The option_string
contains the options to be processed.
If an option is received but not found in option_string
the result option will be set to the ?
character.
If the first character in option_string
is :
then OPTARG
will be set to the option character found, otherwise a message will be written to the standard error and OPTARG
will be unset.
If and option in option_string
is followed by a :
character that option expects an argument and the argument will be set in OPTARG
.
If the argument is not passed and the first character in option_string
is :
then OPTARG
will be set to the option character and the result option will be set to :
character, otherwise the result will be set to the ?
character, a message will be written to the standard error and OPTARG
will be unset.
After all the options are processed, OPTIND
will be set to the index of the first argument left.
The code
#!/bin/bash
declare -i flag_a=0
declare -i flag_b=0
declare arg_b=''
OPTIND=1
while getopts ":ab:c" option; do
case $option in
a) # a option received
((flag_a++));;
b) # b option received
((flag_b++))
arg_b="$OPTARG"
;;
\?) printf '[%s] is an invalid option!\n' "$OPTARG"
exit 1;;
:) printf '[%s] needs an argument!\n' "$OPTARG"
exit 1;;
*) # this is the default processing case
printf '[%s] is not processed!\n' "$option"
exit 1;;
esac
done
if ((flag_a > 0)); then
printf 'Received flag [-a]\n'
fi
if ((flag_b > 0)); then
printf 'The argument for [-b] option is %s\n' "$arg_b"
fi
shift "$((OPTIND-1))"
if (($# > 0)); then
printf 'The are %d remaining arguments:\n' "$#"
printf '%s\n' "$@"
fi
When called with -a -b bbb ccc ddd
options and arguments string, the previous script will print:
Received flag [-a]
The argument for [-b] option is bbb
The are 2 remaining arguments:
ccc
ddd