流程如何通过管道找到与之通信的进程的pid?

时间:2012-09-20 06:17:03

标签: unix process ipc pipe pid

假设我有以下管道:

$ generator_process | filter_process | storage_process

filter_process是否有可能找到generator_processstorage_process的pid?如果是这样,怎么样?如果没有,为什么?

更一般地说,流程如何通过管道找到与之通信的进程的pids?

我正在寻找一种便携式(POSIX)方法来实现这一目标,但如果它需要一些特定于平台的技巧,我正在寻找Linux解决方案。我想C中的答案会给出大部分细节,但如果它涉及shell,我正在寻找一个bash解决方案。

请假设我可以更改filter_process,但generator_processstorage_process是我无法或不想改变的程序(它们可能是我不想要的标准Unix工具摆弄)。此外,将它们包装在将其pid写入磁盘的脚本中并不是我想要的解决方案。

1 个答案:

答案 0 :(得分:2)

请注意,管道的一端可能同时在多个进程中打开(通过fork()sendmsg文件描述符传输),因此您可能不会得到一个答案。

在Linux中,您可以检查/proc/<pid>/fd以查看它已打开的fds(您需要root,或与目标进程相同的uid)。我刚刚运行grep a | grep b并得到以下输出:

/proc/10442/fd:
total 0
dr-x------ 2 nneonneo nneonneo  0 Sep 20 02:19 .
dr-xr-xr-x 7 nneonneo nneonneo  0 Sep 20 02:19 ..
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 0 -> /dev/pts/5
l-wx------ 1 nneonneo nneonneo 64 Sep 20 02:19 1 -> pipe:[100815116]
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 2 -> /dev/pts/5

/proc/10443/fd:
total 0
dr-x------ 2 nneonneo nneonneo  0 Sep 20 02:19 .
dr-xr-xr-x 7 nneonneo nneonneo  0 Sep 20 02:19 ..
lr-x------ 1 nneonneo nneonneo 64 Sep 20 02:19 0 -> pipe:[100815116]
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 1 -> /dev/pts/5
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 2 -> /dev/pts/5

因此,通过在您自己的进程的fd上使用readlink,然后在您拥有的其他进程fds上使用readlink,您可以找出谁在管道的另一端。

疯狂地发现(从Bash脚本中)找出哪些pid和fds连接到特定管道的方法:

get_fd_target() {
    pid=$1
    fd=$2
    readlink /proc/$pid/fd/$fd
}

find_fd_target() {
    target=$1
    for i in /proc/*/fd/*; do
        if [ "`readlink $i`" == "$target" ]; then
            echo $i
        fi
    done
}

然后,如果你想知道系统上的fds连接到你的脚本的stdin:

find_fd_target `get_fd_target $$ 0`