It is widespread to display and store command output using tee utility, but taking full advantage of it requires applying a slightly different error catching strategy.


The exit status of the whole pipeline will be determined by the exit code of the last command.

$ false | tee /tmp/temporary_logfile
$ echo $?

Solution #1

Set pipefail option, so the exit status of the whole pipeline will be defined as the value of the rightmost command that returned a non-zero exit code.

I have placed commands between parentheses to execute these in a subshell environment, so this option does not remain in effect after the subshell completes.
$ (set -o pipefail; false | tee /tmp/temporary_logfile)
$ echo $?

This solution is sufficient for simple cases where you execute a single command and copy its output to a file. I am using it most of the time.

Solution #2

This solution is suitable for advanced cases where you use multiple commands and want to verify exit status for each command in the pipeline, which is especially useful inside custom-built shell scripts.

It uses PIPESTATUS array variable that contains a list of exit status values from the processes in the most recently executed pipeline.

$ false | nonexistent | command | tee /tmp/1
$ echo ${PIPESTATUS[@]}
1 127 0 0

More detailed description.

$ false | nonexistent | command | tee /tmp/1
$ echo -e "false: ${PIPESTATUS[0]}\nnonexistent: ${PIPESTATUS[1]}\ncommand: ${PIPESTATUS[2]}\ntee /tmp/1: ${PIPESTATUS[3]}"
false: 1
nonexistent: 127
command: 0
tee /tmp/1: 0