set -e
BashERRORNotableScriptingHIGH confidence

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.

What this means

`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.

Why it happens
  1. 1Any command returns non-zero when set -e is active
  2. 2A subshell command fails in a context where errexit is active
  3. 3grep, test, or [ ] returns 1 (no match / false) in unexpected places
How to reproduce

A script with set -e halts when grep finds no matches.

trigger — this will error
trigger — this will error
#!/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

Allow specific commands to fail with || true
#!/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

Use if to explicitly handle command failures
#!/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.

What not to do

Remove set -e to silence unexpected exits

set -e is a valuable safety net; instead, explicitly handle the commands you expect might fail.

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Bash errors