プロセスの深さをリストする方法は?

プロセスの深さをリストする方法は?

わずかに異なるプロセスツリーの問題があります。スカラー値としてプロセスとその深さをリストする必要があります。pstree結果は「グラフィックとして」提供されます。

root      100930  0.0  0.3 839396 49020 ?        Ssl  Aug15  38:20 /usr/sbin/rsyslogd -n
root      847414  0.0  0.0  76640  7788 ?        Ss   Aug24   0:00 /usr/sbin/sshd -D 
root     2471773  0.0  0.0 161028 11436 ?        Ss   16:26   0:00  \_ sshd: root [priv]
root     2471790  0.0  0.0 161028  6492 ?        S    16:26   0:00      \_ sshd: root@pts/0
root     2471791  0.0  0.0  17064  5744 pts/0    Ss   16:26   0:00          \_ -bash
root     2483408  0.0  0.0  48064  4260 pts/0    R+   19:13   0:00              \_ ps auxf

ただし、これをテーブルに一覧表示し、深さ> 3、4、5などでプロセスをフィルタリングできると便利です。

PID 親プロセスPID 深さ プロセス
100930 1 システムログ
847414 1 SSHD
2471773 847414 2 SSHD
2471790 2471773 サム SSHD
2471791 2471790 4 強く打つ
2483408 2471791 5 アクセシビリティ

どんなアイデアがありますか?

PS:これらの質問は似ていますが、まさに私が意味するものではありません。 BashですべてのプロセスのPID、PPID、深さ、その他の情報を取得する方法は? 私はどれくらいの深い殻を持っていますか?

ベストアンサー1

私のOpenBSDシステム(Ubuntuでもテスト済み):

$ ps -o pid=,ppid=,command= -ax | awk '{ parent[$1] = $2; cmd[$1] = $3 } function depth(p) { if (p == "" || p == 1) return 1; else return depth(parent[p]) + 1 } END { for (p in parent) print p, parent[p], depth(p), cmd[p] }' | mlr --n2p --barred label PID,PPID,Depth,Command then sort -n Depth,PID
+-------+-------+-------+---------------------------+                                                                                                               01:51:28 [30/1957]
| PID   | PPID  | Depth | Command                   |
+-------+-------+-------+---------------------------+
| 1     | 0     | 1     | /sbin/init                |
| 5555  | 1     | 2     | /usr/sbin/smtpd           |
| 8624  | 1     | 2     | /usr/local/sbin/obsdfreqd |
| 11258 | 1     | 2     | ssh:                      |
...
| 25177 | 78190 | 4     | tmux:                     |
| 39399 | 42657 | 4     | zsh                       |
| 61862 | 42657 | 4     | awk                       |
| 90021 | 65371 | 4     | /usr/local/bin/syncthing  |
+-------+-------+-------+---------------------------+

美しく印刷されたコマンドパイプライン:

ps -o pid=,ppid=,command= -ax |
awk '
{
    parent[$1] = $2
    cmd[$1] = $3
}
function depth(p) {
    if (p == "" || p == 1)
        return 1
    else
        return depth(parent[p]) + 1
}
END {
    for (p in parent)
        print p, parent[p], depth(p), cmd[p]
}' |
mlr --n2p --barred \
    label PID,PPID,Depth,Command then \
    sort -n Depth,PID

このpsコマンドは生の入力データを提供し、システム内の各プロセスのPID、PPID、およびコマンド文字列を出力してこれを実行します。

これはreadですawk。各PIDの親エントリを配列に保存しparent、コマンドの最初の単語をcmd配列に保存します。これらの配列のキーはPIDで指定されます。

その後、コードは、awkPID、PPID、深さ、および各PIDのコマンド文字列の最初の単語を出力します。深さdepthは、PID 1を持つプロセス(または親プロセスがない場合は、さまざまなコンテナを多数実行しているシステムで発生する)までPIDを再追跡し、深さの累積を呼び出し元に再度伝播する再帰関数によって計算されます。招集者。

mlr最後のコマンドは、純粋に出力フォーマットを指定してソートするために使用されます。 Millerを使用して、スペースで区切られたデータを読み取り、トークン化し、奥行きフィールドとPIDフィールドで並べ替えて、きれいに印刷された表形式の出力を生成します。このmlrコマンドは次のように置き換えることができます。

sort -k 3,3n -k 1,1n | column -t

深さフィルタリングの場合、Millerは別の処理ステップを追加してから、たとえば追加するだけで済みthenますfilter '$Depth > 3'

awkMillerを使用したくない場合は、Filterを使用することもできます。column -t出力をパイプで接続すると、awk '$3 > 3'深さが3より大きいすべての行が抽出されます。深さに応じて、printより大きなコードを宣言することもできます。awk

END {
    for (p in parent)
        if ((d = depth(p)) > 3)
            print p, parent[p], d, cmd[p]
}

おすすめ記事