考虑:
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
命令显示在进程树中。