The Template — Add This to Every Script
This is the safest way to start any bash script. Copy this header and build from here.
What you just added
set -euo pipefail combines three safety flags into one line. trap ... ERR tells bash what to print when something fails, including the exact line number. Without these, bash will happily run 50 more lines after an error as if nothing happened.
Step-by-Step Setup
Step 1 — Create a new script file
Paste the template above, then press Ctrl+X → Y → Enter to save.
Step 2 — Add it to an existing script
Open any script you already have and paste set -euo pipefail and the trap line immediately after #!/bin/bash:
That is all you need. Two lines change every script from "silently broken" to "stops and tells you where it failed."
Step 3 — Make it executable and run it
The script exits immediately on the first failed command and prints the line number. Without an error, it completes normally — you will not see any extra output from the trap.
Step 4 — Test the error trap deliberately
Add a failing command to verify the trap fires:
Run it. You should see:
The second echo never executes. That is set -e working correctly. Remove the test line and build from there.
What Each Flag Does
| Flag | Long form | What it does |
|---|---|---|
-e | set -o errexit | Stop immediately if any command exits non-zero. Without this, bash ignores failures and keeps running. |
-u | set -o nounset | Treat any unset variable as an error. Without this, $UNDEFINED_VAR silently becomes an empty string — which can cause catastrophic path errors. |
-o pipefail | pipeline failure | A pipeline fails if ANY command in it fails, not just the last one. Without this, false | true succeeds because only true is checked. |
Why This Actually Matters — Real Examples
The dangerous default (no flags)
What happens without -e
The cd fails. Bash ignores it and stays in the current directory. rm -rf * then runs in whatever directory you were already in — potentially deleting everything there. The script prints "Done." You have no idea anything went wrong.
With set -e (safe version)
What happens with -e
The cd fails. The trap fires and prints "Error on line 5." The script stops completely. rm -rf * never runs. Your files are safe.
The undefined variable trap (why -u matters)
Without -u, a typo can delete your entire system
$TARGER_DIR is undefined so bash replaces it with an empty string. The command becomes rm -rf /* — which attempts to delete everything from the root of your filesystem. With set -u, bash would immediately error: "TARGER_DIR: unbound variable" and stop.
Allowing Commands to Fail Intentionally
Sometimes you want a command to fail without stopping the script. There are two clean ways to do this:
Method 1 — Append || true
Method 2 — Use an if statement
The trap Command — Know Exactly What Line Failed
Adding trap gives you a stack trace when things go wrong. Here are the most useful versions:
Quick Reference — All Flags
| Flag | Long form | What it does |
|---|---|---|
| set -e | set -o errexit | Exit immediately on any error |
| set -u | set -o nounset | Error on undefined variables |
| set -o pipefail | — | Pipeline fails if any stage fails |
| set -x | set -o xtrace | Print every command before running it (debug mode) |
| set +e | — | Turn off -e temporarily for a block |
| set +x | — | Turn off debug mode |
Frequently Asked Questions
What does set -euo pipefail do in bash?
set -e exits on any error. set -u treats undefined variables as errors instead of silently using empty strings. set -o pipefail makes pipelines fail if any stage fails rather than only checking the last command. Together they make bash scripts safe and predictable.
Why do bash scripts keep running after an error?
By default, bash ignores non-zero exit codes and continues executing. This is a design decision for interactive use — a typo in a shell session shouldn't kill your terminal. But in scripts it's dangerous. set -e changes this behavior so scripts stop on the first failure.
What is the difference between set -e and set -o errexit?
They are identical. set -e is shorthand for set -o errexit. Both cause immediate exit on command failure. The short form is more common in scripts.
How do I handle errors in a bash script properly?
Add set -euo pipefail right after #!/bin/bash. Add trap 'echo Error on line $LINENO' ERR for visibility. For commands that are allowed to fail, append || true or wrap them in if statements.