确定管道中的相邻进程是否已执行

确定管道中的相邻进程是否已执行

我的管道中有一系列流程:

cat haystack | grep needle | my_process | less

我的理解是 shell 分叉并同时为每个命令运行 execve 。

在 my_process 中,假设我已经确定了它们的 PID,我如何确定 grep 和 less 是否已完全启动(execve'd)?

答案1

好吧,在 Linux 上,你可以检查:/proc/PID/exe

(p=$BASHPID; /bin/ls -l /proc/$p/exe; exec /bin/ls -l /proc/$p/exe)
... 0 Jan 17 10:34 /proc/17816/exe -> /bin/bash
... 0 Jan 17 10:34 /proc/17816/exe -> /bin/ls

但我真的看不出这有什么好处,外壳程序不会在 之前读取/写入管道exec,因此即使在 之前有一小段时间窗口,管道也可以无缝工作exec。事实上,这是一个小的exec在一段时间内,如果您甚至可以到达那里检查正在运行的程序时已经发生了,我不会感到惊讶。

答案2

这就是继承打开文件描述符的目的。

建立一个 FIFO。在父 shell 中打开一个 close-on-exec 只写文件描述符。所有fork()ed 子级都会继承它,然后在 时关闭它execve()。在需要检测 的进程中为其打开一个只读文件描述符execve(),或者让该进程继承一个已经打开的只读文件描述符。当只写端被 关闭时execve(),只读端将返回EOF。

为了检测个体execve(),可推广到多个 FIFO。事实上,到那时你就不用费心去处理 FIFO 了只需使用第二组管道,其写入文件描述符设置为 close-on-exec。

因为你还没有解释这实际上是什么为了,弄清楚如何将其构建到您实际尝试做的事情中,这只是您的任务。

答案3

仅限 Linux 并带有zsh,

$ autoload zsh/stat
$ (zstat +link /proc/*/fd/0(e'{[[ $REPLY -ef /proc/self/fd/1 ]] &&
    reply=$REPLY:h:h/exe}')) | cat
/bin/cat

这为您提供了与在其标准输入上打开的子 shell 的标准输出具有相同管道的进程的可执行文件的路径。所以上面那个时候,cat已经被执行了。

相关内容