Exit Codes
Bash · Reference cheat sheet
Exit Codes
Bash · Reference cheat sheet
📋 Overview
Every command returns an 8-bit exit status: 0 success, 1–255 failure. Scripts should exit with meaningful codes. $? holds the last foreground status; with pipefail, pipelines report the rightmost non-zero (or zero if all succeed).
🔧 Core concepts
| Code | Convention |
|---|---|
0 | Success |
1 | General error |
2 | Misuse of shell builtins / bad usage (common) |
126 | Found but not executable |
127 | Command not found |
128+N | Fatal signal N (e.g. 130 = SIGINT) |
255 | Out-of-range exit (wrapped) |
| Tool | Role |
|---|---|
exit N | End shell/script with status N |
return N | End function with status N |
$? | Last status |
set -e | Exit on failure (with caveats) |
set -o pipefail | Pipeline status |
sysexits.h codes (EX_USAGE=64, etc.) appear in some tools but are optional for scripts.
💡 Examples
Check and propagate:
if ! git pull; then
echo "pull failed: $?" >&2
exit 1
fiMeaningful script exits:
usage() { echo "usage: $0 <file>" >&2; exit 2; }
[[ $# -eq 1 ]] || usage
[[ -f "$1" ]] || { echo "missing file" >&2; exit 1; }Capture without losing status:
output="$(cmd)" || status=$?
status=${status:-0}Pipeline:
set -o pipefail
false | true # status 1 with pipefail; 0 without⚠️ Pitfalls
exitwith values outside 0–255 are truncated modulo 256.cmd || trueswallows failures—use only when intentional.set -eis disabled in some contexts (if,&&,||,!)—know the rules.- Assignments:
local x=$(false)may not triggerset -eas expected. - Background jobs:
wait $pidyields that job’s status. - Don’t parse
$?after another command overwrote it—save immediately.