Bash Strict Mode: set -euo pipefail Explained

Master bash strict mode with set -euo pipefail. Learn what each flag does, common pitfalls, and how to handle expected failures gracefully.

Script Setup

Detailed Explanation

Bash Strict Mode

Adding set -euo pipefail near the top of your script enables three safety settings that catch most common scripting bugs before they cause damage.

The Three Flags

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

set -e (errexit): Exit immediately if any command returns a non-zero status. Without this, the script continues after failures, potentially operating on stale or missing data.

set -e
cd /nonexistent/path  # Script exits here
rm -rf *              # Never reached

set -u (nounset): Treat unset variables as an error. Without this, $TYPO silently expands to an empty string.

set -u
echo "$UNSET_VAR"  # Error: UNSET_VAR: unbound variable

set -o pipefail: Return the exit status of the first failing command in a pipeline. Without this, only the last command's exit status is used.

set -o pipefail
false | true  # Pipeline fails (false returned non-zero)
echo "This line is not reached with set -e"

Handling Expected Failures

Sometimes a command is allowed to fail. Use these patterns:

# Pattern 1: || true
grep "pattern" file.txt || true  # OK if grep finds nothing

# Pattern 2: if statement
if grep -q "pattern" file.txt; then
  echo "Found"
fi

# Pattern 3: Temporarily disable
set +e
risky_command
result=$?
set -e

Common Pitfalls

Command substitution in local: The local keyword masks the exit status of the command substitution:

# BAD: local masks the error
local result=$(failing_command)  # No error raised!

# GOOD: declare and assign separately
local result
result=$(failing_command)  # Error properly raised

The Full Template

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

# Your script here

The IFS line restricts word splitting to newlines and tabs, providing an extra layer of safety.

Use Case

Every bash script should start with strict mode unless there is a specific reason not to. It is especially important for deployment scripts, data processing pipelines, system administration tasks, and any script where silent failures could cause data loss.

Try It — Shell Script Linter

Open full tool