Free — no signup required

Writing Robust Scripts: set -e, set -u, and pipefail

2 min read

Stop the Madness!

By default, Bash is dangerously permissive. A script with ten commands will run all ten even if command three fails catastrophically. In automation, this leads to disasters: deploying a build that failed to compile, running a database migration against the wrong database, or deleting files based on an empty variable.

The solution is a standard three-flag safety header that every production script should start with — set -e, set -u, and set -o pipefail, usually combined into one call. Here is what each does:

set -e (Exit on error):
Causes the script to exit immediately if any command exits with a non-zero status. This is the "fail fast" principle: stop at the first sign of trouble rather than compounding errors.

set -u (Treat unset variables as errors):
Without this, referencing an unset variable silently expands to an empty string — which turns a typo'd variable name in a path into a silent, catastrophic wildcard: rm -rf /${UNDEFINED_VAR}/data with an unset UNDEFINED_VAR becomes rm -rf /data, deleting far more than intended, with no error at all. With set -u, the same script exits immediately with an "unbound variable" error instead.

set -o pipefail (Pipeline failure propagation):
set -e alone has a critical weakness with pipes. In a two-stage pipeline, Bash only checks the exit code of the last command. If the first command fails but the second one succeeds anyway, the pipeline as a whole is considered successful and set -e never triggers — a report generator that crashes but still hands empty input to an uploader would "succeed" and silently upload nothing. pipefail closes that gap: if any command in the pipeline fails, the whole pipeline is treated as failed.

Key Point: set -u occasionally causes friction with scripts that intentionally check whether optional variables are set. The workaround is to use the default-value expansion ${VAR:-} (which expands to an empty string if unset, satisfying set -u) or ${VAR:-default_value}. This is not a reason to omit set -u — it is a reason to be explicit about which variables are optional.

Interview Tip

A common interview question is: "What does set -euo pipefail do, and why would you use it?" The answer should cover all three flags and their interaction. The follow-up is often: "Can set -e cause unexpected behavior?" Yes — commands used as if conditions are exempt, but commands in subshells or command substitutions may not behave as expected. Demonstrating awareness of these edge cases signals senior-level Bash knowledge.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free