Frequently Asked Question

How do exit codes work in a pipeline and what does set -o pipefail do?

Every command returns an exit code: 0 means success, anything from 1 to 255 means failure (with conventional meanings depending on the program). The shell makes it available in $? immediately after the command runs. In a pipeline like a | b | c, every stage has its own exit code, but bash by default only reports the last one in $?. So if a fails catastrophically but c still finishes cleanly, the pipeline looks successful.

set -o pipefail changes that: the pipeline's exit code becomes the rightmost non-zero code, or zero only if everything succeeded. Combined with set -e (exit on error) and set -u (error on undefined variables), it forms the "unofficial strict mode" you'll see at the top of well-written bash scripts. It matters enormously for things like curl http://example.com | gunzip | tar -xf -: without pipefail, a 404 from curl is invisible because tar happily exits 0 having unpacked nothing.

Further reading and video