わずかに異なるプロセスツリーの問題があります。スカラー値としてプロセスとその深さをリストする必要があります。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で指定されます。
その後、コードは、awk
PID、PPID、深さ、および各PIDのコマンド文字列の最初の単語を出力します。深さdepth
は、PID 1を持つプロセス(または親プロセスがない場合は、さまざまなコンテナを多数実行しているシステムで発生する)までPIDを再追跡し、深さの累積を呼び出し元に再度伝播する再帰関数によって計算されます。招集者。
mlr
最後のコマンドは、純粋に出力フォーマットを指定してソートするために使用されます。 Millerを使用して、スペースで区切られたデータを読み取り、トークン化し、奥行きフィールドとPIDフィールドで並べ替えて、きれいに印刷された表形式の出力を生成します。このmlr
コマンドは次のように置き換えることができます。
sort -k 3,3n -k 1,1n | column -t
深さフィルタリングの場合、Millerは別の処理ステップを追加してから、たとえば追加するだけで済みthen
ますfilter '$Depth > 3'
。
awk
Millerを使用したくない場合は、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]
}