Americas

  • United States
sandra_henrystocker
Unix Dweeb

Using bash options to change the behavior of scripts

How-To
Oct 05, 20225 mins
Linux

Here are some of the more popular bash options to control how scripts work on Linux and how to list the available options, including seeing which ones are turned on.

interconnecting gears / process / automation / machinery / mechanism / efficiency

Bash provides a large number of options that can be used to control the behavior of bash scripts. This post examines some of the more useful ones and explains how to display which options are in use and which are not.

Exiting when an error occurs

If you want a bash script to exit soon as it encounters an error—any error at all—in your scripts, you can add the set -o errexit option. If your script contains a syntax error, tries to read a file that doesn’t exist, attempts to append to a file when you don’t have permission to do so, or misuses a command in some way, the script will end abruptly. Here is a simple example:

#!/bin/bash

set -o errexit

tail NoSuchFile
echo -n “Enter text to be appended> “
read txt
echo $txt >> NoSuchFile

Try to run this script, and you’ll see this:

$ app2file
tail: NoSuchFile: No such file or directory

Because NoSuchFile doesn’t exist, the script exits, and the prompt for text to be appended to it is never run. Without the errexit setting, the script would continue running after the “No such file” error and would collect any text entered after the prompt, create the file, and add the text to it.

Tracing a bash script

Using the xtrace option, every command in a script that is run will be displayed. This option is especially useful when you are debugging a complex script. You can simply remove the xtrace option or comment out that line when you no longer need the command tracing.

#!/bin/bash

set -o xtrace

for day in Sun Mon Tue Wed Thu Fri Sat
do
    echo $day
    sleep 2
done

The output from this script would begin like what is shown below. Lines beginning with + signs would not appear if the xtrace option were not being used.

$ loop-days-of-week
+ for day in Sun Mon Tue Wed Thu Fri Sat
+ echo Sun
Sun
+ sleep 2
+ for day in Sun Mon Tue Wed Thu Fri Sat
+ echo Mon
Mon
+ sleep 2
+ for day in Sun Mon Tue Wed Thu Fri Sat
+ echo Tue
Tue
…

Stopping at unbound variables

Scripts will generally ignore variables that haven’t been defined. If you use the nounset option as shown in the example below, they will exit rather than continue running.

$ cat NoSuchVar
#!/bin/bash

set -o nounset

echo $1
echo $2
$
$ NoSuchVar 1
1
./NoSuchVar: line 6: $2: unbound variable

Using the short form for options

It’s generally more helpful to set options in scripts using their full names as this makes the scripts more readable, but you can elect to use their short forms. For example, the xtrace option can be invoked with the command set -o xtrace as in the example shown earlier. It can, however, also be set using the simpler command set -x. Many of the bash options have single-character names like this that can be used in the “set -?” format. This information can be found in the bash man page, but the list below should make this easier.

Option          Short Form
======          ==========
allexport       -a
braceexpand     -B
errexit         -e
errtrace        -E
functrace       -T
hashall         -h
histexpand      -H
keyword         -k
monitor         -m
noclobber       -C
noexec          -n
noglob          -f
notify          -b
nounset         -u
onecmd          -t
physical        -P
privileged      -p
verbose         -v
xtrace          -x

Display the options

To generate a list of options available with bash and whether they’re active or not, you can use the set -o command with no arguments. I used the set -o | column command on the command line to generate the output below and adjusted it lightly to make the columns line up so it would be easier to read since the column alignment was thrown off by the one lengthy option name (interactive-comments).

allexport       off     ignoreeof               off     nounset         off
braceexpand     on      interactive-comments    on      onecmd          off
emacs           on      keyword                 off     physical        off
errexit         off     monitor                 on      pipefail        off
errtrace        off     noclobber               off     posix           off
functrace       off     noexec                  off     privileged      off
hashall         on      noglob                  off     verbose         off
histexpand      on      nolog                   off     vi              off
history         on      notify                  off     xtrace          off

Note that most of the bash options are turned off.

To see which options are enabled in a script, use the same set -o command. The script shown below will list the active options as shown above, but will also display the active options in a terse one-letter-per-option format.

#!/bin/bash

set -o
echo ===========================
printf %sn “$-“

Here is a sample of its output:

allexport       off
braceexpand     on
emacs           off
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      off
history         off
ignoreeof       off
interactive-comments    on
keyword         off
monitor         off
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off
===========================
hB

Note that the “h” and “B” on the last line in this output reflect the status of the hashall (h) and braceexpand (B) options.

Wrap-Up

There’s a lot more to learn about how to use the options available in bash to control how scripts run. I hope this post gets you off to a good start.

sandra_henrystocker
Unix Dweeb

Sandra Henry-Stocker has been administering Unix systems for more than 30 years. She describes herself as "USL" (Unix as a second language) but remembers enough English to write books and buy groceries. She lives in the mountains in Virginia where, when not working with or writing about Unix, she's chasing the bears away from her bird feeders.

The opinions expressed in this blog are those of Sandra Henry-Stocker and do not necessarily represent those of IDG Communications, Inc., its parent, subsidiary or affiliated companies.