Why can Bash error handling with set -e, pipelines, subshells, and traps still fail silently in production scripts?
Quick Answer
Bash error handling is contextual: `set -e` does not behave like exceptions, pipeline status usually reflects the last command unless `pipefail` is set, and subshells can hide variable changes. Reliable production scripts combine strict mode, explicit checks, traps, quoting, and small testable functions.
Detailed Answer
A shell script is like a checklist read over a noisy radio. If the operator only says whether the final step worked, earlier failures can disappear unless every handoff repeats the status clearly.
Bash favors interactive command composition and POSIX heritage, not modern exception semantics. That makes it powerful for glue work but risky for deployment automation unless failure paths are made explicit.
Commands return numeric statuses, lists and conditionals decide whether those statuses abort execution, pipelines aggregate statuses by shell options, and traps run on configured signals or pseudo-signals such as ERR and EXIT.
At scale, deployment scripts should log commands, validate required variables, use temporary directories safely, lock shared operations, and treat partial failure as normal. Engineers monitor script exit codes, duration, retries, and side effects such as half-written files.
A classic gotcha is grep pattern file | awk ... succeeding because awk ran even when grep failed, or cmd || cleanup suppressing errexit behavior in places the author did not expect. Senior engineers make important checks boring and explicit.
Code Example
#!/usr/bin/env bash
set -Eeuo pipefail # Fails on unset variables, failed pipelines, and most command errors.
trap 'echo "deploy failed at line $LINENO" >&2' ERR # Reports the failing line for incident triage.
: "${SERVICE:?SERVICE is required}" # Stops early if the required service name is missing.
kubectl rollout status "deploy/${SERVICE}" -n payments --timeout=180s # Waits for the rollout and returns non-zero on timeout.Interview Tip
A junior engineer typically answers with the feature name and a happy-path command, but for a senior/architect role, the interviewer is actually looking for production judgment. Explain where the Bash control plane stores intent, how changes are rolled out, what telemetry proves the system is healthy, and what failure mode creates the largest blast radius. Strong answers include rollback behavior, ownership boundaries, permissions, and the exact signal you would page on.