Can I stop later parts of a pipeline from running if an earlier part failed?

岁酱吖の 提交于 2021-01-29 03:01:03

问题


I have a piped command such as:

set -euxo pipefail

echo 'hello' | foo | touch example.sh

This is the output:

$ set -euxo pipefail
$ echo hello
$ foo
$ touch example.sh
pipefail.sh: line 4: foo: command not found

I thought set -e would cause the script to exit however. But even though foo is unrecognized, the script is still executing the touch command. How do I get it to exit if foo fails?


回答1:


You can't really think of a pipeline of having "earlier" or "later" parts, except insofar as data moves through them from one end to the other: All parts of a pipeline run at the same time.

Consequently, you can't prevent later parts from starting if an earlier part failed, because the later part started at the same time the earlier part did.


The above being said, there are mechanisms to allow a pipeline to shut down early in the event of a failure -- mechanisms which work the same way without needing to set any non-default shell flags at all:

  • If you're using a tool designed to be used on the right-hand side of a pipeline (unlike touch), it will be reading from stdin -- and will thus see an early EOF should the components to the left of it fail.
  • If you're using a tool designed to be used on the left-hand side of a pipeline, it will receive a SIGPIPE when it attempts to write if the thing to the right of it is no longer running.

Of course, these mechanisms don't work if you're piping from a program that doesn't write to stdout, or into a program that doesn't read from stdin -- but such programs don't make much sense to use in pipelines anyhow.



来源:https://stackoverflow.com/questions/51957772/can-i-stop-later-parts-of-a-pipeline-from-running-if-an-earlier-part-failed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!