Writing defensive Bash scripts

From ben.goodacre.name/tech

Jump to: navigation, search

Any kind of script should be written to expect the unexpected, this is known as programming defensively.


Exit on error

set -o errexit

The script will exit if any statement returns a non-zero exit code. Ensure that no statement or command returns a non-zero exit code as part of its normal operation as this option could cause the script to break where it might otherwise have worked.

Exit on use of missing variable

set -o nounset

The script will exit if any statement attempts to refer to a missing variable. Commands can have very-undesired affects if a variable returns, consider rm -Rf $var/etc/apache2.

Using $?

The $? environment variable will not work if set -o errexit is set as BASH will exit on the line before. The following can be used as an alternative:

/bin/command || { echo "error";exit 1; }

Expect for files to be missing

mkdir -p /path/to/dir
rm -f file

Create parent folders if they do not exist and do not return a non-zero value if files do not exist with rm.

Always use quotes around variables

Otherwise a space will cause statements using it fail usually.

Be prepared for the script to be killed or otherwise exit early

The trap command allows a command or sub to be run upon the script receiving a signal. There are many signals that can be trapped but three most useful are:

Signal Case
INTInterupt - user presses Ctrl+C
TERMTerminate - user kills the script using kill
EXITTriggered when the script exits normally or from a condition using the set command.

To clear up temp files upon exiting normally or abnormally:

trap "rm -f /tmp/file; exit" INT TERM EXIT

Different traps can be configured by specifiying the signals in separate commands.

Personal tools