Cautious Bash

When you are creating Bash automation, you should avoid surprises. There are three bash options that can shield you from unexpected errors:

  • set -e exit on errors
  • set -u exit on undefined variables
  • set -o pipefail exit on errors within piped commands
Image of axe, dagger, mace, and shield
Source: Pixabay

To set all three at the top of your bash script, it will look like this:

#!/usr/bin/env bash
set -euo pipefail

Once you have done this, your scripts automatically exit once any of the steps fail. You can change this:

tar -xf staging-dir.tar || exit
mv staging-dir production-dir || exit
service nginx restart || exit
echo success

To this:

tar -xf staging-dir.tar
mv staging-dir production-dir
service nginx restart
echo success

Where’s my error?

Sometimes you’ll need to catch an error and keep going. For example, sometimes grep returns an “error” code, but you want to handle that yourself instead of exiting.

Normally you could use grep like this:

if [ grep do_magic config_file ]; then
  echo casting spell
else
  echo bashing with mace
fi

However since you already set -euo pipefail, the script will exit instead of bashing with the mace!

You can now either set +e, then grep, then set -e, OR you can add a bit more magic syntax to your bash script, like this:

if [[ $(grep do_magic config_file) ]]; then
  echo casting spell
else
  echo bashing with mace
fi