❗ Error Handling
Error handling in POSIX shells is subtle and often misunderstood.
Shells do not fail fast by default, pipelines hide errors, and subshells discard state.
This module provides practical techniques for writing reliable, production‑grade scripts.
🎓 Who This Is For
- Engineers writing automation or CI/CD pipelines
- DevOps/SRE teams maintaining production scripts
- Developers migrating from bash to POSIX sh
- Anyone needing predictable failure behavior
🧩 Role in the Ecosystem
Shells provide minimal built‑in error handling.
Correctness depends on:
- Exit codes
- Conditional checks
- Traps
- Strict mode (bash/ksh)
- Defensive programming
This module complements
Traps & Signals
and
Debugging Scripts.
🧩 Key Concepts
1. Exit Codes
Commands return 0 on success, non‑zero on failure.
2. Conditional Execution
| command || exit 1
command && echo ok
|
3. set -e (bash/ksh)
Stops execution on unhandled errors — but with many exceptions.
4. pipefail
Ensures pipelines fail if any stage fails.
5. Traps
Used for cleanup and controlled shutdown.
🔧 Techniques
Explicit Error Checks
| if ! command; then
echo "failed" >&2
exit 1
fi
|
Strict Mode (bash/ksh)
POSIX‑Safe Error Handling
| command || {
echo "error: command failed" >&2
exit 1
}
|
Required Variables
| : "${TOKEN:?TOKEN is required}"
|
Cleanup on Error
| trap 'rm -f "$TMPFILE"' EXIT
|
Fail Fast in Pipelines
⚠️ Limitations & Pitfalls
set -e does not work reliably in POSIX sh
- Pipelines hide failures without
pipefail
- Subshells discard variable changes
- Traps behave differently across shells
- Error messages printed to stdout break scripts
- Bash‑only features break portability
🧠 When to Use These Techniques
- Writing robust automation
- Handling temporary files or resources
- Ensuring CI/CD stops on failure
- Validating required configuration
- Preventing silent data corruption
❌ When Not to Use Them
- Extremely small scripts
- Legacy scripts relying on implicit behavior
- Highly portable
/bin/sh scripts requiring strict POSIX compliance
- Scripts where partial failure is acceptable
✅ Best Practices
- Always check exit codes explicitly
- Use
set -euo pipefail in bash/ksh scripts
- Use traps for cleanup
- Print errors to stderr:
- Avoid complex logic inside traps
- Keep error messages consistent and machine‑parsable
- Test under multiple shells
🧪 Testing Error Handling
| set -e
false
echo "unreachable"
|
Test pipeline behavior:
| set -o pipefail
false | true
echo $? # 1
|
Test required variables:
| : "${TOKEN:?missing TOKEN}"
|
🧠 Summary
Error handling in shell scripts requires explicit checks, strict mode, traps, and defensive programming.
Used correctly, these techniques prevent silent failures and make automation predictable and safe.