web-dev-qa-db-ja.com

現在実行中のプロセスから分岐されたプロセスのリストを取得しますか?

スクリプトをbashするラッパーアプリケーションを作成していて、アプリケーションがユーザースクリプトから起動されたツール/プロセスを追跡したいと考えています。 this親プロセスから生成された子プロセスのリストを決定する最良の方法は何ですか?.

私は試した

  1. 定期的にpsコマンドを呼び出して、プロセスツリーを構築します(ps -ejHなど)。
  2. Procコネクタインターフェイスを使用するforkstatのようなツールを使用しますが、これは昇格された特権でのみ実行されます。これは正しいデータを提供しますが、私の場合、Sudoとして実行すると機能しませんか?

これをどのように達成できるかについての提案はありますか?

3
divyanshm

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 ...>
_

スクリプトはclone(2)システムコールを使用して3つのプロセス(PID 4818、4819、4820)を分岐し、分岐されたプロセスのexecve(2)システムコールは実行されたコマンドを示します。 。

  • _-e fork,vfork,clone,execve_ strace出力をこれらのシステムコールに制限します
  • _-f_は子プロセスに従います
  • _-b execve_は、execveに到達するとプロセスから切り離されるため、子プロセスのトレースがさらに表示されることはありません。
6
muru

pgrep コマンドが役立ちます。次のコマンドを使用します。

分岐した各プロセスのPIDをprocess($pid):

pgrep -P $pid

フォークされた各プロセスの詳細については、次のコマンドを使用してください。

ps -fp `pgrep -P $pid`

どこ $pidはプロセスIDです。

3
finn
pstree -p `pgrep NetworkManager`
NetworkManager(1638)─┬─dhclient(3594)
                     ├─{NetworkManager}(1645)
                     ├─{NetworkManager}(1647)
                     └─{NetworkManager}(7363)

これはあなたが探していたものだと思います。

プロセス名で直接pidまたはpgrepを使用します。

-pは、子供のPIDを出力するために使用されます。

3
Devidas