如何获取将输出转储到 stdout 的所有进程的 PID。
答案1
所有进程都有一个标准输出并且可以写入它。如果你想找到那些标准输出是当前终端的进程,在Linux上你可以使用
find -L /proc/[0-9]*/fd/1 -prune -samefile /dev/stdout
类似的
find -L /proc/[0-9]*/fd/2 -prune -samefile /dev/stdout
将识别其标准错误是当前终端的进程。您可以将两者结合起来
find -L /proc/[0-9]*/fd/[12] -prune -samefile /dev/stdout
但这并不能告诉您他们是否实际上正在写入当前终端。
要实际记录写入其标准输出的所有 PID,您可以使用bpftrace,如果您的内核支持 eBPF(许多发行版内核现在都支持 eBPF;请参阅内核bpftrace
要求详情):
sudo bpftrace -e 'kprobe:ksys_write /comm != "bpftrace" && arg0 == 1/ { printf("PID %d writing to stdout\n", pid); }'
这会将每次写入记录到标准输出(文件描述符 1),除了来自bpftrace
自身的写入(因为该bpftrace
程序写入标准输出,所以它最终只记录自身)。
答案2
与其他人不同,我认为您的问题没有多大意义,或者更确切地说,我怀疑您犯了一个错误?
非常具体地说,Stdout 只是一个文件描述符 FD1。
每个打开 FD1 的进程(即/proc/self/fd/1
在 Linux 上)都可能写入标准输出。
这真的是您想知道的吗?
如果是,那么bftrace
@Stephen Kitt 的示例是让进程实际写入 FD1 的唯一方法,但仅限于那些在跟踪器过滤器运行时写入的进程。
如果你没问题,即使所有可能的作家也sudo lsof | egrep ' 1u| 1w'
应该这样做(并且返回更大的集合)。
但是如果你问,什么写入“当前” tty
(可能是你在终端中看到的),那是完全不同的事情,因为即使进程关闭了 FD1,它也可以让你的 tty 在任何其他 FD 上打开,狂野,甚至在 FD777901700 上也是如此。
在这种情况下,您必须识别有问题的 tty 并对其进行过滤sudo lsof | grep 'CHR' | grep '/dev/yourtty'
。