Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cause a Linux pipeline to fail?

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:

  • 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??
  • Is there a way to simulate a pipeline failure?? We can use false to simulate the failure of a command. Is there a similar command for a pipeline?
like image 916
yaobin Avatar asked Sep 02 '25 06:09

yaobin


2 Answers

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.

Example

This pipeline succeeds:

$ false | true | false | true ; echo $?
0

This pipeline fails:

$ set -o pipefail
$ false | true | false | true ; echo $?
1

Documentation

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.

like image 189
John1024 Avatar answered Sep 04 '25 19:09

John1024


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.

like image 21
John Kugelman Avatar answered Sep 04 '25 20:09

John Kugelman