如果较早的部分出现故障,是否可以停止管道的较晚部分运行?

时间:2018-08-21 22:57:08

标签: bash shell pipe

我有一个管道命令,例如:

DECLARE @word VARCHAR(200) = 'This,Is,A,Sentence'

;WITH
a AS (SELECT i=-1, j=0 UNION ALL SELECT j, CHARINDEX(',', @word, j + 1) FROM a WHERE j > i),
b AS (SELECT SUBSTRING(@word, i+1, IIF(j>0, j, LEN(@word)+1)-i-1) word FROM a WHERE i >= 0)
SELECT * FROM b

这是输出:

set -euxo pipefail

echo 'hello' | foo | touch example.sh

我认为$ set -euxo pipefail $ echo hello $ foo $ touch example.sh pipefail.sh: line 4: foo: command not found 会导致脚本退出。但是,即使无法识别set -e,该脚本仍在执行foo命令。如果touch失败,如何退出?

1 个答案:

答案 0 :(得分:3)

您无法真正想到具有“较早”或“较晚”部分的管道,除非数据通过它们从一端移动到另一端:管道的所有部分同时运行

因此,如果较早的部分出现故障,您将无法阻止以后的部分开始运行,因为因为较早的部分是在较早的部分发生故障的同时启动的。


上面说的是,有 种机制可以使管道在发生故障时尽早关闭-这些机制的工作方式相同,而无需设置任何非默认的shell标志完全没有:

  • 如果您使用的是设计用于管道右侧的工具(与touch不同),它将从stdin中读取内容-因此,如果组件处于早期状态,则会出现EOF左边的失败。
  • 如果您使用的是专为在管道左侧使用的工具,则当它右边的东西不再运行时,它在尝试编写时会收到SIGPIPE

当然,如果从不写到stdout的程序或不从stdin读取的程序中进行管道传输,这些机制将不起作用-但是这样的程序没有多大意义可以在管道中使用。