管道中的下一个程序可以看到前一个程序的退出代码吗?

dan*_*dan 8 shell bash pipe exit

我想制作一个像这样的 Bash 脚本管道

prog1 | prog2

这样 prog2 就可以看到 prog1 的退出代码并根据该信息采取不同的行动。

这可能吗?

Gil*_*il' 4

一般的答案是否定的。甚至可以在启动prog2之前退出prog1(显然,如果实际读取一些输入,则不会发生prog2这种情况,如果您在管道中使用它,则您希望它这样做)。prog2之前退出肯定是有可能的prog1;例如,当prog2搜索程序一找到匹配项就退出时,就会发生这种情况,在这种情况下,prog1可能尚未完成生成所有数据。

\n\n

没有直接的方法可以prog2检索退出状态prog1,甚至知道它prog1已经退出。我们prog2所能知道的就是它prog1已经关闭了管道的末端,它可以做到这一点而不会死亡。

\n\n

如果你想获取prog1from的退出状态prog2,有两种常用的方法:可以将其写入文件,也可以通过管道发送。可以将输出状态作为管道数据的最后一行发送。您必须确保不要处理最后一行,直到您知道它是最后一行,即直到您尝试读取下一行。

\n\n
{ prog1; echo $?; } | \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

下面是一个示例,其中右侧是一个文本过滤器,它将包含单词 \xe2\x80\x9cerror\xe2\x80\x9d 的每一行着色为红色。如果左侧失败,右侧将以相同的状态退出。

\n\n
{ prog1; echo $?; } | awk \'\n    NR != 1 {\n        if (line ~ /[Ee][Rr][Rr][Oo][Rr]/) print "\\033[31m" line "\\033[0m";\n        else print line;\n    }\n    {line = $0}\n    END {exit($0)}\n\'\n
Run Code Online (Sandbox Code Playgroud)\n