Parsing Command-line Options in Shell Scripts Using `getopts`

What is getopts

getopts is a built-in Unix shell command for parsing command-line options. It is a wrapper around getopt, a POSIX C library function used to parse command-line options of the Unix/POSIX style. Specifically:

  • Options are single-character alphanumerics preceded by a - (hyphen-minus) character, i.e. -a. -b, -c.
  • Options can take an argument or none.
  • Multiple options can be chained together, as long as the non-last ones are not argument-taking. If -a and -b take no arguments while -c takes an argument, -abc foo is the same as -a -c -e foo, but -bca is not the same as -b -c a due to the preceding rule.
  • When an option takes an argument, this can be in the same token or in the next one. In other words, if -c takes an argument, -cfoo is the same as -c foo.

optstring's

Both getopt and getopts specifies specify options using a optstring. Specifically:

  • Begin an optstring with :.
  • To specify an option that does not take an argument, append its name to the optstring.
  • To specify an option that takes an argument, append its name and : to the optstring.

For example, the optstring that specifies two options -a, -b that do not take arguments and two options -c, -d that take arguments is :abc:d:.

Using getopts in a Shell Script

In Shell scripts, getopts invoked with an optstring is used with a while-loop to parse command-line options.

Say that our Shell script test_getopts.sh accepts two options -a, -b that do not take arguments and two options -c, -d that take arguments. Our Shell script can look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/sh

while getopts ':abc:d:' name
do
case $name in
a)
echo "You provided option -a"
;;
b)
echo "You provided option -b"
;;
c)
echo "You provided option -c with argument $OPTARG"
;;
d)
echo "You provided option -d with argument $OPTARG"
;;
:)
echo "Option -$OPTARG requires an argument"
;;
?)
echo "You provided an invalid option -$OPTARG"
;;
esac
done

Here, getopts is invoked with the optstring for specifying our options, :abc:d:. In each iteration of the while-loop, the next option is parsed and the Shell variables name and OPTARG are set to different values based on different conditions we may encounter.

  • If a valid option is detected and that option does not take an argument, the Shell variable name is set to the name of the option.
  • If a valid option is detected and that option takes an argument:
    • If we have provided an argument, the Shell variable name is set to the name of the option, and the Shell variable OPTARG is set to the value of the argument.
    • If we haven't provided an argument, the Shell variable name is set to :, and the Shell variable OPTARG is set to the name of the argument.
  • If an invalid option is detected, the Shell variable name is set to ?, and the Shell variable OPTARG is set to the name of the argument.

We can see getopts at work by providing different command-line options when invoking our Shell script.

Providing no command-line options:

1
$ sh test_getopts.sh

Providing option -a that do not take arguments:

1
2
$ sh test_getopts.sh -a
You provided option -a

Providing option -a that do not take arguments twice:

1
2
3
4
5
6
$ sh test_getopts.sh -a -a
You provided option -a
You provided option -a
$ sh test_getopts.sh -aa
You provided option -a
You provided option -a

Providing option -c that takes an argument with an argument foo:

1
2
$ sh test_getopts.sh -c foo
You provided option -c with argument foo

Providing option -c that takes an argument with an argument foo twice:

1
2
3
$ sh test_getopts.sh -c foo -c bar
You provided option -c with argument foo
You provided option -c with argument bar

Providing option -c that takes an argument without an argument:

1
2
$ sh test_getopts.sh -c
Option -c requires an argument

Providing an invalid argument -e:

1
2
$ sh test_getopts.sh -e
You provided an invalid option -e

References

  • https://en.wikipedia.org/wiki/Getopts
  • https://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
  • https://en.wikipedia.org/wiki/Getopt
  • https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html

Parsing Command-line Options in Shell Scripts Using `getopts`
https://abbaswu.github.io/2023/06/09/Parsing-Command-line-Options-in-Shell-Scripts-Using-getopts/
Author
Jifeng Wu
Posted on
June 9, 2023
Licensed under