为什么使用“ps”命令时“cat /tmp/out1 > /tmp/in2 &”显示为“bash”?

为什么使用“ps”命令时“cat /tmp/out1 > /tmp/in2 &”显示为“bash”?

考虑:

mkfifo /tmp/out1
mkfifo /tmp/in2
cat /tmp/out1 > /tmp/in2 &

当我跑步时

ps 

它看起来如参考资料 部分bash中所示CMD

为什么?

答案1

ps列表巴什作为正在运行的进程,因为 bash 进程/tmp/in2在生成cat命令之前尝试打开 fifo 时被阻止。由于bash它负责处理您的redirect( > /tmp/in2),因此它必须首先打开,/tmp/in2以便稍后可以使用dup2系统调用将命令STDOUT的更改cat为 的文件描述符/tmp/in2。不幸的是,open在这种情况下,调用被阻塞。

如果您要在 strace 中运行命令:

strace -f bash -c "cat /tmp/out1 > /tmp/in2"

你会看到它停在:

[pid 18457] open("/tmp/in2", O_WRONLY|O_CREAT|O_TRUNC, 0666

它会被阻塞,直到另一个进程打开该文件进行读取。根据先进先出(7)手册页:

内核为至少一个进程打开的每个 FIFO 特殊文件维护一个管道对象。必须先打开 FIFO 两端(读和写),然后才能传递数据。通常,打开 FIFO 会阻塞,直到另一端也打开为止。

进程可以以非阻塞模式打开 FIFO。在这种情况下,即使尚未有人在写入端打开,以只读方式打开也会成功,而仅以写入方式打开将因 ENXIO(没有此类设备或地址)而失败,除非另一端已打开。

如果您要先打开/tmp/in2阅读(例如cat /tmp/in2 &在最终的 cat 命令之前添加),您将看到最终的cat命令显示在进程树中。

相关内容