似乎变量“PIPESTATUS”在dash
. 简单的单独执行不起作用,因为左侧命令会产生非常大的输出。我使用了一个fifo来完成这个任务:
#!/bin/dash
mkfifo command1 command2
dash -c "cat ./content;code=\${?};echo \${code} > command1 &" | dash -c "md5sum;code=\${?};echo \${code} > command2 &"
echo "$(cat ./command1)" "$(cat ./command2)"
但我不知道为什么它挂了?
您可以使用命名管道并手动连接两个进程。以相反的顺序启动它们,因此左侧在前台运行,您可以
$?
像往常一样获得其退出状态。或者如果你想要两者,获取后台进程的 PID
$!
并wait
获取退出状态。你仍然可以将管道的第二部分留在前景中,我只是想对称地做。
例如,您还可以将退出状态存储到文件中,然后从那里获取它们:
我认为命名管道在这里用处不大,因为退出状态只有几个字节。
exit1
在尝试读取和exit2
第二行之前,shell 将等待管道完成。如果要改用命名管道,则需要将管道置于后台,因为对管道的写入会阻塞,直到打开读取端为止。
但是,如果
cat
读取管道的 s 由于某种原因没有运行,则写入它们的子shell 将在后台无限期地阻塞。在实际命令退出后,您可以通过关闭管道左侧的标准输出和右侧的标准输入来解除脚本:
例子:
将 替换为
(...; exit ..)
您各自的命令。在实际命令退出后关闭管道右侧的标准输入导致左侧的 write() 接收 SIGPIPE 或 EPIPE 而不是在尝试
echo ... >fifo &
从右侧管道传输到命令时阻塞(它本身被阻塞在 open()) 中,关闭左侧的 stdout 会导致管道右侧的 read() 接收 EOF,而不是尝试从echo ... >fifo &
左侧的阻塞进行管道传输。感谢@ilkkachu 的更正。