Process
獲取從我目前執行的程序中分叉的程序列表?
我正在為 bash 腳本編寫一個包裝應用程序,並希望該應用程序跟踪已從使用者腳本啟動的工具/程序。我想知道確定由該父程序生成的子程序列表的最佳方法是什麼。
我試過
- 定期呼叫ps命令並建構程序樹(如 ps -ejH),但這會錯過執行很快完成的程序。
- 使用像forkstat這樣的工具,它使用 proc 連接器介面,但只能以提升的權限執行。雖然這提供了正確的數據,但以 sudo 執行在我的情況下不起作用?
有什麼建議可以實現嗎?
如果您使用的是 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 ...>
您可以看到腳本使用系統呼叫分叉了三個程序(PID 4818、4819、4820)
clone(2)
,並且execve(2)
這些分叉程序中的系統呼叫顯示了執行的命令。
-e fork,vfork,clone,execve
將 strace 輸出限制為這些系統呼叫-f
跟隨子程序-b execve
到達時從程序中分離execve
,因此我們看不到對子程序的進一步跟踪。