프로세스의 깊이를 나열하는 방법은 무엇입니까?

프로세스의 깊이를 나열하는 방법은 무엇입니까?

약간 다른 프로세스 트리 문제가 있습니다. 스칼라 값으로 프로세스와 그 깊이를 나열해야 합니다. 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 접근성

어떤 아이디어가 있나요?

추신: 이 질문들은 비슷하지만 정확히 제가 의미하는 바는 아닙니다. 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]
}

관련 정보