Process

獲取從我目前執行的程序中分叉的程序列表?

  • November 22, 2018

我正在為 bash 腳本編寫一個包裝應用程序,並希望該應用程序跟踪已從使用者腳本啟動的工具/程序。我想知道確定由父程序生成的子程序列表的最佳方法是什麼。

我試過

  1. 定期呼叫ps命令並建構程序樹(如 ps -ejH),但這會錯過執行很快完成的程序。
  2. 使用像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,因此我們看不到對子程序的進一步跟踪。

引用自:https://unix.stackexchange.com/questions/481693