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.