假设我有以下管道:
$ generator_process | filter_process | storage_process
filter_process
是否有可能找到generator_process
和storage_process
的pid?如果是这样,怎么样?如果没有,为什么?
更一般地说,流程如何通过管道找到与之通信的进程的pids?
我正在寻找一种便携式(POSIX)方法来实现这一目标,但如果它需要一些特定于平台的技巧,我正在寻找Linux解决方案。我想C中的答案会给出大部分细节,但如果它涉及shell,我正在寻找一个bash解决方案。
请假设我可以更改filter_process
,但generator_process
和storage_process
是我无法或不想改变的程序(它们可能是我不想要的标准Unix工具摆弄)。此外,将它们包装在将其pid写入磁盘的脚本中并不是我想要的解决方案。
答案 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`