The getopts syntax

Instead of spending any more time in this chapter not seeing actual code, we're going to jump right in and show a very simple example of a getopts script. Of course, we'll walk you through step by step so that you have the chance to understand it all.

The script we're creating does just a few simple things: if it finds the -v flag, it prints a verbose message, telling us it found the flag. If it does not find any flags, it prints nothing. If it finds any other flag, it prints an error for the user. Simple, right?

Let's take a look:

reader@ubuntu:~/scripts/chapter_15$ vim single-flag.sh
reader@ubuntu:~/scripts/chapter_15$ cat !$
cat single-flag.sh
#!/bin/bash

#####################################
# Author: Sebastiaan Tammer
# Version: v1.0.0
# Date: 2018-12-08
# Description: Shows the basic getopts syntax.
# Usage: ./single-flag.sh [flags]
#####################################

# Parse the flags in a while loop.
# After the last flag, getopts returns false which ends the loop.
optstring=":v"
while getopts ${optstring} options; do
case ${options} in
v)
echo "-v was found!"
;;
?)
echo "Invalid option: -${OPTARG}."
exit 1
;;
esac
done

If we run this script, we'll see the following happening:

reader@ubuntu:~/scripts/chapter_15$ bash single-flag.sh # No flag, do nothing.
reader@ubuntu:~/scripts/chapter_15$ bash single-flag.sh -p
Invalid option: -p. # Wrong flag, print an error.
reader@ubuntu:~/scripts/chapter_15$ bash single-flag.sh -v
-v was found! # Correct flag, print the message.

So, our script at least works as expected! But why does it work like that? Let's take a look. We'll skip the header, as that should be very clear by now. We'll start with the while line, which contains the getopts command and optstring:

# Parse the flags in a while loop.
# After the last flag, getopts returns false which ends the loop.
optstring=":v"
while getopts ${optstring} options; do

optstring, which is likely short for options string, tells getopts which options should be expected. In this case, we expect only v. However, we start the optstring with a colon (:), which is a special character for optstring that sets getopts in silent error reporting mode.

Since we prefer to handle error situations ourselves, we will always start our optstring with a colon. However, feel free to see what happens when you remove the colon.

After that, the syntax for getopts is pretty simple, as follows:

getopts optstring name [arg]

We can see the command, followed by the optstring (which we abstracted to a separate variable to improve readability), ending with the name of the variable in which we'll store the parsed results.

The final, optional, aspect of getopts allows us to pass our own set of arguments, instead of defaulting to everything passed to the script ($0 through $9). We will not be needing/using this in our exercises, but this is definitely good to know. As always, because this is a shell builtin, you can find information on it by executing help getopts.

We place this command within a while loop so that it iterates over all arguments we passed to the script. If there are no more arguments to be parsed by getopts, it returns an exit status other than 0, which causes the while loop to exit.

While we're inside the loop, though, we'll hit the case statement. As you know, the case statement is basically better syntax for a longer if-elif-elif-elif-else statement. In our example script, this looks like this:

  case ${options} in
v)
echo "-v was found!"
;;
?)
echo "Invalid option: -${OPTARG}."
exit 1
;;
esac
done

Notice how the case statement ends with the word esac (case in reverse). For all our defined flags (currently only -v), we have a block of code that will execute only for that flag.

The other thing we find when we look at the ${options} variable (which we have because we specified it for name in the getopts command) is the ? wildcard. We place that at the end of the case statement as a means of catching errors. If it hits the ?) code block, we've presented getopts with a flag it does not understand. In this case, we print an error and exit the script.

The done on the last line ends the while loop, and signals that all of our flags should have been handled.

It might seem a bit unnecessary to have both an optstring and a case for all possible options. For now, this is indeed the case, but a bit further on in this chapter we'll show you how the optstring is used to specify things beyond just the letter; at that point, it should be clear why the optstring is here. For now, don't worry about it too much and just enter the flags in both locations.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.171.107