Bash getopts builtin command
Updated:
02/01/2021
by
Computer Hope
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
Syntax
How it works
Specifying the
optstring
Verbose error checking
Silent error checking
Specifying custom arguments
Examples
Related commands
Bash builtins help
Linux commands index
Description
getopts
is the bash version of another system tool,
getopt
. Notice that the bash command has an
s
at the end, to differentiate it from the system command.
While the
getopt
system tool can vary from system to system, bash
getopts
is defined by the
POSIX
standard. So if you write a script using
getopts
, you can be sure that it runs on any system running bash in POSIX mode (e.g.,
set
-o posix
).
getopts
parses short options, which are a single dash ("
-
") and a letter or digit. Examples of short options are
-2
,
-d
, and
-D
. It can also parse short options in combination, for instance
-2dD
.
However,
getopts
cannot parse options with long names. If you want options like
--verbose
or
--help
, use
getopt
instead.
Syntax
getopts optstring optname [ arg ]
How it works
getopts
processes the
positional parameters
of the parent command. In bash, this is stored in the shell variable "
$@
". So, if you run this command:
mycmd -a argument1 -b argument2
During the time that
mycmd
is running, the variable
$@
contains the string "
-a argument1 -b argument2
". You can use
getopts
to
parse
this string for options and arguments.
Every time you run getopts, it looks for one of the options defined in
optstring
. If it finds one, it places the option letter in a variable named
optname
. If the option does not match those defined in
optstring
, getopts sets variable
optname
to a question mark ("
?
").
If the option is expecting an argument, getopts gets that argument, and places it in
$OPTARG
. If an expected argument is not found, the variable
optname
is set to a colon ("
:
"). Getopts then increments the positional index,
$OPTIND
, that indicates the next option to be processed.
The special option of two dashes ("
--
") is interpreted by
getopts
as the end of options.
getopts
is designed to run multiple times in your script, in a
loop
, for example. It processes one option per loop iteration. When there are no more options to be processed,
getopts
returns false, which automatically terminates a
while
loop. For this reason,
getopts
and
while
are frequently used together.
Specifying the optstring
optstring
is a
string
which defines what options and arguments
getopts
look for. For instance, in this call to getopts:
getopts "apZ" optname
The options expected by getopts are
-a
,
-p
, and
-Z
, with no arguments. These options can be combined in any order as
-aZ
,
-pa
,
-Zap
, etc.
Let's say that you'd like the
-a
and
-Z
options to take arguments. You can specify this by putting a colon ("
:
") after that option in
optstring
. For example:
getopts "a:pZ:" optname
Now you can specify arguments to the
-a
and
-Z
options such as
-a argument1 -pZ argument2
. The
-p
option cannot take arguments, because there is no colon after the
p
in
optstring
.
There are two reserved characters which cannot be used as options: the colon ("
:
") and the question mark ("
?
").
Verbose error checking
By default,
getopts
will report a
verbose
error if it finds an unknown option or a misplaced argument. It also sets the value of
optname
to a question mark ("
?
"). It does not assign a value to
$OPTARG
.
If the option is valid but an expected argument is not found,
optname
is set to "
?
",
$OPTARG
is unset, and a verbose error message is printed.
Silent error checking
However, if you put a colon at the beginning of the
optstring
, getopts runs in "silent error checking mode." It will not report any verbose errors about options or arguments, and you need to perform error checking in your script.
In silent mode, if an option is unexpected, getopts sets
optname
to "
?
" and
$OPTARG
to the unknown option character.
If the option is OK but an expected argument is not found,
optname
is set to a
colon
("
:
") and
$OPTARG
is set to the unknown option character.
Specifying custom arguments
You will usually want
getopts
to process the arguments in
$@
, but in some cases, you may want to manually provide arguments for getopts to parse. If so, you can specify these
args
as the final argument of the
getopts
command.
Examples
Here is a bash script using
getopts
. The script prints a greeting, with an optional name, a variable number of times. It takes two possible options:
-n
NAME
and
-t
TIMES
.
#!/bin/bash
NAME="" # Name of person to greet.
TIMES=1 # Number of greetings to give.
usage() { # Function: Print a help message.
echo "Usage: $0 [ -n NAME ] [ -t TIMES ]" 1>&2
exit_abnormal() { # Function: Exit with error.
usage
exit 1
while getopts ":n:t:" options; do # Loop: Get the next option;
# use silent error checking;
# options n and t take arguments.
case "${options}" in #
n) # If the option is n,
NAME=${OPTARG} # set $NAME to specified value.
t) # If the option is t,
TIMES=${OPTARG} # Set $TIMES to specified value.
re_isanum='^[0-9]+$' # Regex: match whole numbers only
if ! [[ $TIMES =~ $re_isanum ]] ; then # if $TIMES not whole:
echo "Error: TIMES must be a positive, whole number."
exit_abnormal
elif [ $TIMES -eq "0" ]; then # If it's zero:
echo "Error: TIMES must be greater than zero."
exit_abnormal # Exit abnormally.
:) # If expected argument omitted:
echo "Error: -${OPTARG} requires an argument."
exit_abnormal # Exit abnormally.
*) # If unknown (any other) option:
exit_abnormal # Exit abnormally.
if [ "$NAME" = "" ]; then # If $NAME is an empty string,
STRING="Hi!" # our greeting is just "Hi!"
else # Otherwise,
STRING="Hi, $NAME!" # it is "Hi, (name)!"
COUNT=1 # A counter.
while [ $COUNT -le $TIMES ]; do # While counter is less than
# or equal to $TIMES,
echo $STRING # print a greeting,
let COUNT+=1 # then increment the counter.
exit 0 # Exit normally.
If this script is named
greeting
, here's what the output looks like with different options:
./greeting
./greeting -n Dave
Hi, Dave!
./greeting -t 3
./greeting -t 4 -n Betty
Hi, Betty!
Hi, Betty!
Hi, Betty!
Hi, Betty!
./greeting -n
Error: -n requires an argument.
Usage: ./greeting [ -n NAME ] [ -t TIMES ]
./greeting -t
Error: -t requires an argument.
Usage: ./greeting [ -n NAME ] [ -t TIMES ]
./greeting -t -1
Error: TIMES must be a positive, whole number.
Usage: ./greeting [ -n NAME ] [ -t TIMES ]
./greeting -t 0
Error: TIMES must be greater than zero.
Usage: ./greeting [ -n NAME ] [ -t TIMES ]
while — Execute a set of actions while a certain condition is true.