div*_*shm 6 process ps process-management
我正在为 bash 脚本编写一个包装应用程序,并希望该应用程序跟踪从用户脚本启动的工具/进程。我想知道确定由该父进程产生的子进程列表的最佳方法是什么。
我试过
任何建议如何实现?
如果您使用的是 Linux,则可以用于strace
跟踪进程使用的系统调用。例如:
~ strace -e fork,vfork,clone,execve -fb execve -o log ./foo.sh
foo bar
~ cat log
4817 execve("./foo.sh", ["./foo.sh"], [/* 42 vars */]) = 0
4817 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4818
4818 execve("/bin/true", ["/bin/true"], [/* 42 vars */] <detached ...>
4817 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4818, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
4817 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4819
4817 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4820
4820 execve("/bin/echo", ["/bin/echo", "foo", "bar"], [/* 42 vars */] <detached ...>
4817 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4820, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
4817 +++ exited with 0 +++
4819 execve("/bin/sleep", ["sleep", "1"], [/* 42 vars */] <detached ...>
Run Code Online (Sandbox Code Playgroud)
您可以看到脚本使用clone(2)
系统调用分叉了三个进程(PID 4818、4819、4820),并且execve(2)
这些分叉进程中的系统调用显示了执行的命令。
-e fork,vfork,clone,execve
将 strace 输出限制为这些系统调用-f
跟随子进程-b execve
execve
到达时与进程分离,因此我们看不到对子进程的进一步跟踪。小智 7
pstree -p `pgrep NetworkManager`\nNetworkManager(1638)\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80dhclient(3594)\n \xe2\x94\x9c\xe2\x94\x80{NetworkManager}(1645)\n \xe2\x94\x9c\xe2\x94\x80{NetworkManager}(1647)\n \xe2\x94\x94\xe2\x94\x80{NetworkManager}(7363)\n
Run Code Online (Sandbox Code Playgroud)\n\n我想这就是你正在寻找的。
\n\n使用直接 pid 或 pgrep 和进程名称。
\n\n-p 用于打印子进程的 pid。
\n