Bash by Example: Error Handling
Making scripts robust with strict mode settings including set -e to exit on command failure, set -u to treat unset variables as errors, and set -o pipefail to catch failures in pipelines, understanding the trade-offs of strict mode, implementing proper error handling with these flags, and creating production-ready scripts.
Code
#!/bin/bash
# 1. Exit immediately if a command fails
set -e
# 2. Treat unset variables as an error
set -u
# 3. Fail if any command in a pipe fails
set -o pipefail
echo "Starting strict script..."
# Example of set -u protection
# echo "User is: $UNKNOWN_VAR"
# ^ This would crash the script immediately
# Example of set -e protection
# ls /non_existent_dir
# ^ This would crash the script immediately
# Handling errors gracefully despite set -e
if ls /non_existent_dir 2>/dev/null; then
echo "Dir exists"
else
echo "Dir missing (handled gracefully)"
fi
# Example of pipefail
# Without pipefail, 'ls bad | grep foo' would return 0 (success)
# because grep succeeds (finds nothing).
# With pipefail, the whole pipe returns failure.
if ! ls /bad/path 2>/dev/null | grep "foo"; then
echo "Pipe failed correctly."
fi
echo "Script finished successfully."Explanation
By default, Bash is very forgiving. If a command fails, it just prints an error and moves to the next line. If you use an undefined variable, it treats it as an empty string. While this is fine for interactive use, it is dangerous for automation scripts where one failure can cascade into data loss (e.g., rm -rf /$undefined_var could become rm -rf /).
To make scripts robust, use the "Bash Strict Mode":
set -e (errexit): Abort the script at the first error.
set -u (nounset): Abort if an undefined variable is used.
set -o pipefail: Return the exit code of the last command to fail in a pipe, not just the last command.
Using these settings forces you to write cleaner code. You must handle potential errors explicitly (e.g., using if checks or || true) rather than ignoring them. This significantly increases the reliability of production scripts.
Code Breakdown
set -e ensures that if a critical command like cd fails, the script won't blindly continue executing commands in the wrong directory.set -u prevents "unbound variable" errors. This catches typos in variable names (e.g., $filenmae instead of $filename).set -o pipefail is crucial for pipelines. Normally, cat missing | sort returns 0 because sort succeeds on empty input. Pipefail ensures the failure of cat propagates to the script.
