0

假设我有以下管道:

$ generator_process | filter_process | storage_process

是否有可能filter_process找出generator_process和的pid storage_process?如果是这样,怎么做?如果不是,为什么?

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

我正在寻找一种可移植的(POSIX)方式来做到这一点,但如果它需要一些特定于平台的技巧,那么我正在寻找一个 Linux 解决方案。我想 C 中的答案会给出最详细的信息,但如果它涉及 shell,我正在寻找一个 bash 解决方案。

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

4

1 回答 1

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

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

找出(从 Bash 脚本中)哪些 pids 和 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
}

然后,如果您想找出系统上的哪些 fd 连接到您的脚本的标准输入:

find_fd_target `get_fd_target $$ 0`
于 2012-09-20T06:22:01.223 回答