This problem bit me today, and so I’m going to pass on a solution in hopes it helps someone else.
Suppose you are running the following shell command:
foo | bar | baz
Suppose that foo exits with a non-zero return code, but bar and baz exit with a zero return code. Typically, the shell will only return the exit code of the last program in the pipeline. However, those plucky folks who made GNU bash have given us a way out: the pipefail option. From the bash manpage:
The return status of a pipeline is the exit status of the last command, unless the
pipefailoption is enabled. Ifpipefailis enabled, the pipeline’s return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
To use, just run set -o pipefail in your script to enable the pipefail option.
I discovered this neat trick while debugging the following pipeline:
rake 2>&1 | log_filter.rb | tee buildlog.out
tee always returned 0, and this made determining whether the rake script failed or not impossible until I used pipefail.
Note: this only works in GNU bash >= 3.00.
(Thanks to Bob Clary for the answer.)