我正在尝试使用命名管道,以便我可以保留stdout
长时间过程的状态输出。我可以stderr
用于状态输出,但我想保留它以防出错。这是一个例子:
#!/bin/bash
pipe=$(mktemp -u)
mkfifo $pipe
dd if=/dev/zero of=$pipe bs=1M count=1024 status=progress & cat $pipe > test.bin
# ¿¿¿ Status of dd command ???
rm $pipe
该命令并不完全是我想要做的,但说明了使用命名管道将一个进程的输出馈送到另一个进程的输入的组合。在我的应用程序中,dd
替换为一些长时间运行的命令,并cat
替换为ssh
. 这会做我想要的,但我不知道如何获取dd
命令的状态,因为它$?
会返回命令的状态cat
。如果这是一个管道,我可以使用PIPESTATUS
,但这似乎不适用于并行进程。在实际应用中,任何一个(或两个)命令都可能失败。
有没有办法让进程的状态并行运行?有没有比命名管道更好的方法来完成这个任务?
要获取异步命令的退出状态,请
wait
在其 pid 上使用:(还修复了一些明显的错误,例如不检查那些
mktemp
/的成功mkfifo
,未引用的扩展,缺少--
s)。请注意,如果(或在您的情况下替代的
dd
任何实际命令)在打开写入之前退出,则将无限期地挂在它自己的只读FIFO上。dd
$pipe
cat
open()
为了解决这个问题,您可以
$pipe
在另一个 fd 上为最终运行的进程打开 shell,dd
确保管道在cat
打开时立即实例化(并假设dd
在打开之前不任意关闭该 fd$pipe
):同样,如果
cat
在打开管道之前死亡,您将遇到相同的对称问题,您可以以相同的方式解决。如果您的系统有文件,而不是命名管道,您可能还可以使用普通管道并使用's来检索退出状态:
/dev/fd/n
/dev/fd/n
bash
$PIPESTATUS
(
$PIPESTATUS
是特定于 bash 的,但有其他 shell 的替代方案)。上面,
dd
和cat
都将在他们的 fd 3 上打开管道(对于 的写入端dd
和读取端cat
),并且他们将/dev/fd/3
在管道上打开另一个 fd,就像上面的解决方法一样。我们使用 fds 4 和 5 来恢复两者的原始标准输入和标准输出(尽管这里cat
的标准输出是另外的test.bin
)。