devutils/ATFQ/book ATFQ git

Part III · Shell and commands

27.4 Exit codes

alsoexit codeexit codesexit statusreturn code$?set -epipefail

TL;DR

  • Every command ends with a number: 0 means success, anything else (1 to 255) a failure.
  • $? holds the last one. && runs the next command only on success, || only on failure.
  • 126: found but not executable. 127: command not found. 128 + N: killed by signal N, so 130 is Ctrl-C and 137 is SIGKILL.
grep -q error app.log; echo $?
make && ./install.sh
cd build || exit 1

Pitfalls

Deep dive 2 questions

Where does the number come from?

The program passes it to the kernel when it exits, and the parent reads it with wait(), the same call that clears zombies (see 16.1). The shell adds the conventions for 126, 127 and 128 + N. Some programs give meaning to their codes: for diff and grep, 1 means "different" or "no match", and 2 means an error.

How do I write safer scripts?

Start bash scripts with set -euo pipefail: stop at the first failure, treat unset variables as errors, and count failures inside pipes. Then allow the failures you expect, explicitly, with || true or an if.

Commands
echo
See also
27.3 Redirections and file descriptors
16.2 Signals