Recently I'm learning the set -e
of POSIX shell on Ubuntu 14.04. My reference material is the "IEEE Std 1003.1-2008, 2016 Edition", "Shell & Utilities" chapter. From this section I see -e
doesn't cause the script to quit when the command fails in a pipeline (unless the failed command is the last one in the pipeline):
The failure of any individual command in a multi-command pipeline shall not cause the shell to exit. Only the failure of the pipeline itself shall be considered.
I then wrote a simple script to confirm this behavior:
(
set -e
false | true | false | true
echo ">> Multi-command pipeline: Last command succeeded."
)
(
set -e
false | true | false
echo ">> Multi-command pipeline: Last command failed."
)
The "Last command succeeded" message is printed out, while the "Last command failed" message is not.
My questions are:
false | true | false
don't seem to be a failure of the pipeline. It's just the failure of the last command. The pipeline itself still succeeds. Am I right??false
to simulate the failure of a command. Is there a similar command for a pipeline?By default in bash, the success or failure of a pipeline is determined solely by the last command in the pipeline.
You may however enable the pipefail
option (set -o pipefail
) and the pipeline will return failure if any command in the pipeline fails.
This pipeline succeeds:
$ false | true | false | true ; echo $?
0
This pipeline fails:
$ set -o pipefail
$ false | true | false | true ; echo $?
1
From man bash
:
The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is 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.
The chained commands
false | true | false
don't seem to be a failure of the pipeline. It's just the failure of the last command. The pipeline itself still succeeds. Am I right?
The success of a pipeline is specified to be the success of the last command. They are the same thing.
From §2.9.2 Pipelines:
If the pipeline does not begin with the
!
reserved word, the exit status shall be the exit status of the last command specified in the pipeline. Otherwise, the exit status shall be the logical NOT of the exit status of the last command. That is, if the last command returns zero, the exit status shall be 1; if the last command returns greater than zero, the exit status shall be zero.
In bash and ksh this you can use set -o pipefail
to cause the pipeline to fail if any command in it fails. This is not a POSIX option, unfortunately. It ought to be, but it isn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With