具有自己的 $BASHPID 的子 shell(子进程/子进程)未在 `ps` 中列出

具有自己的 $BASHPID 的子 shell(子进程/子进程)未在 `ps` 中列出

我不明白以下内容:

mkfifo p;
$ (>p ps -f | >>p echo $BASHPID) &
[1] 983527
$ cat p
983529
   PID    PPID  C STIME TTY          TIME CMD
981815  165343  0 19:57 pts/27   00:00:00 bash
983527  981815  0 21:09 pts/27   00:00:00 bash    # <- child bash process `(...)`
983528  983527  0 21:09 pts/27   00:00:00 ps -f
983530  981815  0 21:09 pts/27   00:00:00 cat p

(...) &结果是一个 PID 为 983527 的子进程。它是一个 bash 进程。

ps -f在 PID 为 983528的子进程中执行。(...)它是管道的左侧组件命令...|...

echo $BASHPID报告正在 PID 为 983529 的进程中执行。它应该是管道的右侧组件...|...,并且应该被列为 bash 进程。

最后的解释正确吗?为什么我们看不到ps -f命令​​列出的最后一个进程?

答案1

>p ps -f | >>p echo $BASHPIDinbash同时启动两个子进程,通过管道连接。两个进程都p以只写模式打开 fifo 开始(带有O_APPEND第二个进程的标志,但这对管道没有影响)。

由于该 fifo 还没有读取器,因此两个open()s 都会挂在那里,等待某个进程以读取模式打开 fifo。

因此,在那时,您已经拥有了这两个流程的起点。

左边的仍然需要执行,ps这意味着查找并加载/bin/ps可执行文件,加载动态链接器,加载和链接库,开始读取/proc等等,这是很多工作。虽然正确的做法是 Expand $BASHPID,对其执行 split+glob ,调用echo内置函数(仅调用内部函数),该函数仅写入该扩展并退出。

运行时cat p,只要cat打开fifo,上面的两个进程就会同时解除阻塞。正确的 ( echo) 可能已经完成了简单的工作并在ps完成加载之前很久就退出了,因此ps不会找到它,/proc这解释了为什么您看不到它。


1 并且它的死亡将得到其父进程的确认,否则该进程仍将显示为僵尸进程

相关内容