在我的情况下,第一个命令,即command1,运行一段时间,直到产生一些输出。例如,你可以用command1替换(sleep 5&& echo“Hello”)。
现在,command1 |错误在5秒钟后失败,但不会立即失败。
这个行为似乎与命令产生的输出量有关。例如,找到/ |错误返回立即。
一般来说,我不知道为什么bash的行为是这样的。任何人都可以想象任何有用的代码,如command1 | non-existing-command不会立即退出?
PS:使用临时文件对我来说不是一个选择,因为我围绕的中间结果是大的存储。
PPS:既没有设置也没有设置管道似乎影响这种现象。
Each command in a pipeline is executed in its own subshell […]
“在自己的subshell”意味着一个新的bash进程被产生,然后执行实际的命令。每个子shell成功启动,即使它立即确定要求执行的命令不存在。
这就解释了为什么整个管道可以成功建立,即使其中一个命令是废话。 Bash不检查每个命令是否可以运行,它会将它委托给subshell。这也解释了为什么,例如,命令nonexisting-command | touch hello会抛出一个“命令未找到”错误,但是文件hello将被创建。
在同一节中,它还说:
The shell waits for all commands in the pipeline to terminate before returning a value.
在睡眠5 |非正常命令,正如A.H.指出的,睡眠5在5秒之后终止,而不是立即,所以shell也将等待5秒。
我不知道为什么这样实现。在像你这样的情况下,行为肯定不会像人们期望的那样。
无论如何,一个稍微丑陋的解决方法是使用FIFO:
mkfifo myfifo ./long-running-script.sh > myfifo & whoops-a-typo < myfifo
这里,long-running-script.sh启动,然后脚本在下一行立即失败。使用多个FIFO,这可以扩展到具有两个以上命令的管道。