set -e Will Kill Your Script For No Good Reason
You add set -e to your bash script because you want it to stop on errors. Reasonable expectation. What could go wrong?
Plenty.
The Problem
set -e makes your script exit immediately when any command returns non-zero. Sounds fine until you remember how many things legitimately return non-zero:
grep -q "pattern" file # returns 1 when no match found
curl -s https://example.com # returns non-zero on 4xx/5xx
(( counter > 5 )) # returns 1 when false
None of those are errors. But set -e doesn't care.
Real Example
#!/bin/bash
set -e
# This fails silently when the string isn't found
name=$(grep "^username=" /etc/app/config | cut -d= -f2)
# This fails when count is zero
if (( count > 0 )); then
process_items
fi
The grep returns 1 when there's no match. set -e kills the script. Same with arithmetic that's false.
The Workarounds
Option 1: Disable locally
set -e
grep -q "pattern" file || true # always succeeds
Option 2: Toggle around suspect code
set +e
grep -q "pattern" file
result=$?
set -e
Option 3: Check explicitly
if grep -q "pattern" file; then
name=$(grep "^username=" /etc/app/config | cut -d= -f2)
fi
The Smarter Default
Skip set -e entirely. Check your commands explicitly:
if ! grep -q "pattern" file; then
echo "pattern not found" >&2
exit 1
fi
More verbose, but you control exactly what fails and why.
Why This Bites You At 3am
Because the script worked for months, then one day curl starts returning 404 for a URL that moved, and your whole deploy stops. The actual failure is trivial, but set -e treats it like the world ended.
It's not your logic that's broken. It's set -e being overprotective.
This isn't a reason to never use set -e. Just don't use it without understanding what it actually checks. Most shell script bugs I debug come down to this flag surprising someone at the worst moment.
Top comments (0)