Bash Tutorial: getopts
The getopts command is a built in shell command for parsing command line arguments. It is better than the getopt alternative for several reasons. It's defined in POSIX and has a single implementation that's native to bash. Using getopts , you don't have to hit an external program or provide options in a specific order for it to work. In this tutorial, we run through the basics of using getopts to parse command line arguments for your bash scripts.
getopts basic example
Let's say you have a basic sample.sh script that takes a single option a :
$ ./sample.sh -a
You can implement this as follows:
#!/bin/bash
while getopts "a" opt; do
case $opt in
a)
echo "argument -a called" >&2
;;
esac
done
The output of this script will be:
>argument -a called
Notice how we use the getopts command within a while loop. This iterates through each option in our option string. In this case, our options string is simply "a" .
getopts option with parameter
Let's say you want the option a to accept a parameter:
$ ./sample.sh -a hello
Notice how we are now passing in a parameter hello with the option a . We can implement getopts as follows:
#!/bin/bash
while getopts "a:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
esac
done
The output of this script will be:
argument -a called with parameter hello
Notice the colon in our option string. Any character that is followed by a : indicates that the option takes a parameter.
getopts default errors
What happens if we don't pass a parameter after specifying a: in our option string? The output will be:
./sample.sh: option requires an argument -- a
Bash will throw an error since we specified that the argument a requires a parameter.
For production scripts, you typically want to handle errors yourself. This keeps your code cleaner and gives you more control over the output of your scripts. If you begin the options string with a colon, this enables "silent error mode":
#!/bin/bash
while getopts ":a:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
esac
done
Now when we run the script without a parameter we won't see any error message in the output. This is because we've started the option string with a colon :a: .
getopts handling errors yourself
Even in "silent error mode", you may want to communicate your own message to the user informing them that the command is invalid. You can implement a catch-all for any argument that doesn't match the option string or is missing a parameter:
#!/bin/bash
while getopts ":a:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
*)
echo "invalid command: no parameter included with argument $OPTARG"
;;
esac
done
Now if we don't pass a parameter with the a argument, the output of this script will be:
invalid command: no parameter included with argument a
getopts working with multiple arguments
You can work with any number of arguments in your option string. Let's say you have a script taking two parameters, a and b :
$ ./sample.sh -a hello -b
Notice how the argument a takes a parameter hello while the b argument acts as a flag. We could implement this like so:
#!/bin/bash
while getopts ":a:b" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
b)
echo "argument -b called" >&2
;;
*)
echo "invalid command"
;;
esac
done
The output of this script will be:
argument -a called with parameter hello
argument -b called
Notice how our options string includes a colon after argument a but not argument b . This means the that argument a expects a parameter while b does not. Also remember that the options string starts with a colon. This means "silent error mode" is enabled.
If we wanted both a and b to take parameters like:
$ ./sample.sh -a hello -b goodbye
#!/bin/bash
while getopts ":a:b:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
b)
echo "argument -b called with parameter $OPTARG" >&2
;;
*)
echo "invalid command: no parameter included with argument $OPTARG"
;;
esac
done
The output of this script will be:
argument -a called with parameter hello
argument -b called with parameter goodbye
Conclusion
Working with getopts takes some getting used to but is ultimately the preferred way to parse optional arguments in bash. Remember that optargs is typically used within a while loop to iterate through the different options in the string. Whenever a character is followed by a colon, the argument expects a parameter. Whenever an option string starts with a colon, "silent error mode " is enabled. This gives you more control of your script output.
FYI here is the ChatGPT answer:
The
getopts
command is a Bash built-in command that is used to parse command-line options and arguments in shell scripts. In this tutorial, we'll explore how to use thegetopts
command to process command-line options in a Bash script.Basic Syntax
The basic syntax of the
getopts
command is as follows:The
optstring
argument is a string of option letters that specify the options that the script should recognize. Each letter inoptstring
represents an option that the script will handle. A colon (:
) following an option letter indicates that the option requires an argument.The
varname
argument is the name of the variable that will hold the option letter thatgetopts
recognizes.The optional
args
argument is a list of command-line arguments thatgetopts
will process. Ifargs
is omitted,getopts
will use the positional parameters ($1
,$2
, etc.) as input.Example
Here's an example script that demonstrates how to use the
getopts
command:Let's go through this script line by line:
#!/bin/bash
) is the shebang line that specifies the interpreter to use.getopts
command is used in a while loop to process the command-line options. Theopt
variable holds the current option letter, and theOPTARG
variable holds the value of the argument (if any) associated with the option.case
statement is used to handle each recognized option. In this example, the script handles options-a
and-b
. Theecho
command prints a message to the console indicating which option was recognized and the value of the argument (if any).\?
), the script prints an error message to the console.:
), the script prints an error message to the console.$@
) to the console.Running the Script
Let's assume we have saved the above script as
script.sh
and made it executable withchmod +x script.sh
. We can now run the script with various command-line options and arguments.In this example, we passed the options
-a
and-b
with the argumentsfoo
andbar
, respectively. The positional parameterbaz
is also passed to the script.