我正在寻找一种方法来获取 Linux 中短子进程的 PID。从人的角度来看,该进程是即时的。我知道将生成子进程的父进程。
有没有办法记录有关特定父进程创建的所有进程的信息?
我不是在寻找一种方法来追溯计算出孩子的 PID,而是一种在发生后记录它的方法。
答案1
您可以使用审核系统:
sudo auditctl -a exit,always -S execve -F ppid="$pid"
$pid
会导致每次子进程执行命令时生成审核条目。audit.log
会有类似的东西:
type=SYSCALL msg=audit(1373986729.977:377): arch=c000003e syscall=59 success=yes exit=0 a0=7ff000e4b188 a1=7ff000e4b1b0 a2=7fff928d47e8 a3=7fff928caac0 items=2 ppid=7502 pid=691 auid=10031 uid=10031 gid=10031 euid=10031 suid=10031 fsuid=10031 egid=10031 sgid=10031 fsgid=10031 ses=1 tty=pts5 comm="echo" exe="/bin/echo" key=(null)
type=EXECVE msg=audit(1373986729.977:377): argc=2 a0="/bin/echo" a1="test"
type=CWD msg=audit(1373986729.977:377): cwd="/tmp"
type=PATH msg=audit(1373986729.977:377): item=0 name="/bin/echo" inode=131750 dev=fe:00 mode=0100755 ouid=0 ogid=0 rdev=00:00
在那里你可以找到pid
其他东西。
如果您对不一定执行某些操作的进程感兴趣,您可以为fork
和clone
系统调用添加审核规则。
答案2
[这个答案的灵感来自于此艾迈斯咨询]
如果子进程是一个不同的可执行文件(我们称之为foo
),您可以尝试使用 shell 包装器。
重命名原始可执行文件:
$ cd \path\to\foo\
$ mv foo foo.moved
创建包装器为foo
:
#!/bin/sh
\path\to\foo\foo.moved "$@" &
FOO_PID=$!
echo $FOO_PID >\tmp\foo.pid
使其可执行:
chmod +x foo
下次程序运行时,您将在 中获取 pid \tmp\foo.pid
。
答案3
外壳方法
$!
当您在 shell 中运行命令时,您可以使用Bash shell 中的特殊变量找到在后台运行的最后一个进程的 PID 。
例如:
$ sleep 5 &
$ echo $!
8648
此外,当您后台进程时,该进程的 PID 将通过控制台返回,如下所示:
$ sleep 5 &
[1] 8648
另一种方法是使用pgrep -P <PPID>
.例如:
# PID of bash shell
$ echo $$
8376
# run fake job
$ sleep 120 &
[1] 8891
# pgrep PPID
$ pgrep -P 8376
8891
瓦尔格林德
还有另一种方法,如果您可以在您尝试获取子 PID 的程序执行之前注入以下内容:
$ valgrind --trace-children=yes <cmd>
例如:
# sample.bash
#/bin/bash
ls
$ valgrind --trace-children=yes ./sample.bash
...
==17734== possibly lost: 0 bytes in 0 blocks
==17734== still reachable: 33,606 bytes in 95 blocks
==17734== suppressed: 0 bytes in 0 blocks
==17734== Rerun with --leak-check=full to see details of leaked memory
==17734==
==17734== For counts of detected and suppressed errors, rerun with: -v
==17734== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
==17733==
==17733== HEAP SUMMARY:
==17733== in use at exit: 36,409 bytes in 879 blocks
...
17733 是 PPID,PID 17734 是调用 get ( ls
) 的子 PID。
答案4
如果您的操作系统(o/p 中未指定)不支持进程跟踪,请考虑用包装器替换子映像,假设新进程加载新映像。