Terminal · intermediate

Shell error handling

Shell error handling combines explicit status checks, intentional propagation, validated inputs, cleanup, and selectively enabled shell options rather than relying on exceptions.

Why it matters

Shell commands fail through statuses in many syntactic contexts, and blunt strict-mode folklore can either miss failures or stop on expected negative results.

Mental model

How to reason about shell error handling

Classify each command outcome, handle expected alternatives locally, propagate unexpected nonzero status at a deliberate boundary, and register cleanup for resources already created.

Analogy

It is a checklist with known alternate outcomes and evacuation steps, not a single alarm switch assumed to understand every operation in the building.

Examples

See the boundary, not just the happy path

Worked example · Handle an expected negative result

if grep -qF needle file; then found=yes; elif [ "$?" -eq 1 ]; then found=no; else exit 1; fi

The branches distinguish grep's match, no-match, and error outcomes instead of treating every nonzero result identically.

Worked example · Validate required input early

: "${OUTPUT_DIR:?OUTPUT_DIR must be set}"

Parameter expansion stops a non-interactive shell with a targeted diagnostic before a missing variable can resolve to an unsafe path.

Avoid · Strict mode as a complete strategy

set -euo pipefail

These Bash options can be useful under a documented shell, but context-sensitive errexit behavior and expected nonzero statuses still require explicit design.

Common mistakes

Misconceptions to remove early

Assuming set -e fires after every nonzero status

errexit has specified exceptions in conditionals, lists, and pipelines, and its behavior interacts with functions and shell versions.

Suppressing every error with || true

This erases the distinction between an expected condition and an operational failure; test or document the exact accepted statuses instead.

Quick check

Can you predict the result?

1. Why is set -e not a substitute for explicit error handling?
Answer: Its behavior is context-sensitive and it cannot know which nonzero statuses are expected or how each failure should be recovered.
2. What should a script do with a command that uses distinct nonzero statuses for no result and operational error?
Answer: Inspect and handle the documented statuses separately.

Keep building

Authoritative references

Make the idea retrievable.

Study this concept with spaced repetition, next to the commands where you use it.

Get Terminaster