Bash Error Handling - set -e, trap, Exit Codes, Retry Patterns
Learn robust error handling in bash scripts with set -euo pipefail, trap for cleanup, exit code checking, retry logic, and error reporting patterns.
Detailed Explanation
Error Handling in Bash
Bash scripts fail silently by default. Without proper error handling, a failed command can cause subsequent commands to run with incorrect data or in an unexpected state. Robust error handling is essential for production scripts.
set -euo pipefail
The most important line in any bash script:
set -euo pipefail
- -e (errexit): Exit immediately if any command returns a non-zero exit code
- -u (nounset): Treat references to unset variables as errors
- -o pipefail: A pipeline fails if any command in it fails (not just the last)
Trap for Cleanup
The trap command executes code when the script receives a signal or exits:
cleanup() {
echo "Cleaning up..."
rm -rf "$TEMP_DIR"
# Restore original state
}
trap cleanup EXIT # always run on exit
trap cleanup ERR # run on error
trap 'echo "Interrupted"; exit 1' INT TERM # handle Ctrl+C
Checking Exit Codes
# Method 1: if statement
if ! command_that_might_fail; then
echo "Command failed with exit code $?"
exit 1
fi
# Method 2: || operator
command_that_might_fail || {
echo "Command failed"
exit 1
}
# Method 3: explicit check
command_that_might_fail
status=$?
if [ $status -ne 0 ]; then
echo "Failed with status $status"
fi
Retry Pattern
retry() {
local max_attempts="$1"
local delay="$2"
shift 2
local cmd="$@"
local attempt=1
while [ $attempt -le $max_attempts ]; do
if eval "$cmd"; then
return 0
fi
echo "Attempt $attempt/$max_attempts failed. Retrying in ${delay}s..."
sleep "$delay"
attempt=$((attempt + 1))
done
echo "All $max_attempts attempts failed"
return 1
}
# Usage
retry 3 5 curl -sf https://api.example.com/health
Error Reporting
# Custom error handler
error() {
local line="$1"
local msg="$2"
echo "ERROR at line $line: $msg" >&2
}
trap 'error $LINENO "Script failed"' ERR
# Detailed error logging
log_error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $*" | tee -a error.log >&2
}
Safe Temporary Files
TEMP_DIR=$(mktemp -d) || { echo "Failed to create temp dir"; exit 1; }
TEMP_FILE=$(mktemp) || { echo "Failed to create temp file"; exit 1; }
trap 'rm -rf "$TEMP_DIR" "$TEMP_FILE"' EXIT
Use Case
Error handling is critical for production deployment scripts, backup automation, CI/CD pipelines, and any script that modifies system state. Without proper error handling, a failed database migration could leave the system in an inconsistent state, or a failed backup could go unnoticed. Trap and cleanup patterns ensure resources are always released.
Try It — Bash Cheat Sheet
Related Topics
Bash Script Basics - Shebang, Arguments, Exit Codes, set Options
Script Basics
Bash Functions - Definition, Arguments, Return Values, Scope
Control Flow
Bash If/Else Conditions - Tests, Comparisons, and File Checks
Control Flow
Bash While and Until Loops - File Reading, Polling, Counters
Control Flow
Bash Process Management - ps, kill, top, bg, fg, jobs, nohup
Process Management