Unexpected exit from set -e (errexit)
Production Risk
Common source of confusion in CI pipelines; always pair set -e with || true or if for fallible commands.
`set -e` (errexit) causes the shell to exit immediately if any command returns a non-zero exit code. A script with `set -e` appears to halt unexpectedly when a command fails, often with the exit code of that failing command.
- 1Any command returns non-zero when set -e is active
- 2A subshell command fails in a context where errexit is active
- 3grep, test, or [ ] returns 1 (no match / false) in unexpected places
A script with set -e halts when grep finds no matches.
#!/bin/bash set -e echo "Checking for pattern..." grep "nonexistent" /var/log/syslog # exits 1 if no match echo "This line is never reached"
expected output
Checking for pattern... Exit: 1
Fix 1
Allow specific commands to fail with || true
WHEN A command is allowed to return non-zero
#!/bin/bash set -e grep "pattern" logfile || true # allow grep to find nothing grep -q "pattern" logfile || echo "Pattern not found"
Why this works
|| true ensures the expression always exits 0, preventing set -e from triggering.
Fix 2
Use if to explicitly handle command failures
WHEN The result of the command matters
#!/bin/bash set -e if grep -q "ERROR" /var/log/app.log; then echo "Errors found in log" >&2 exit 1 else echo "No errors" fi
Why this works
set -e does not trigger on the test expression of an if statement; only on unguarded commands.
✕ Remove set -e to silence unexpected exits
set -e is a valuable safety net; instead, explicitly handle the commands you expect might fail.
GNU Bash Manual — The Set Builtin
BashFAQ/105 — Why set -e exits unexpectedly ↗Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev