bash – Shell管道:当一个命令失败时立即退出

前端之家收集整理的这篇文章主要介绍了bash – Shell管道:当一个命令失败时立即退出前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在bash中使用了几个命令的管道。如果一个命令失败,是否有一种方式配置bash以立即终止整个管道中的所有命令?

在我的情况下,第一个命令,即command1,运行一段时间,直到产生一些输出。例如,你可以用command1替换(sleep 5&& echo“Hello”)。

现在,command1 |错误在5秒钟后失败,但不会立即失败。

这个行为似乎与命令产生的输出量有关。例如,找到/ |错误返回立即。

一般来说,我不知道为什么bash的行为是这样的。任何人都可以想象任何有用的代码,如command1 | non-existing-command不会立即退出

PS:使用临时文件对我来说不是一个选择,因为我围绕的中间结果是大的存储。

PPS:既没有设置也没有设置管道似乎影响这种现象。

bash文档在 section about pipelines中说:

Each command in a pipeline is executed in its own subshell […]

“在自己的subshel​​l”意味着一个新的bash进程被产生,然后执行实际的命令。每个子shell成功启动,即使它立即确定要求执行的命令不存在。

这就解释了为什么整个管道可以成功建立,即使其中一个命令是废话。 Bash不检查每个命令是否可以运行,它会将它委托给subshel​​l。这也解释了为什么,例如,命令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@H_301_38@ 
 

这里,long-running-script.sh启动,然后脚本在下一行立即失败。使用多个FIFO,这可以扩展到具有两个以上命令的管道。

猜你在找的Bash相关文章