주어진 PID 또는 명령에서 특정 상위 프로세스를 찾는 수동 작업을 자동화하는 방법은 무엇입니까?

주어진 PID 또는 명령에서 특정 상위 프로세스를 찾는 수동 작업을 자동화하는 방법은 무엇입니까?

나는 전체 명령 "/bin/child_process" 또는 해당 pid(이 경우 3996)를 알고 있으며 실행 중이며 ps auxf그 상위 프로세스를 시각적으로 식별합니다 /bin/parent_process foobar.

root      3227  0.0  0.0    992   296 ?        S<s  10:35   0:00 /bin/parent_process foobar
20058     3987  0.0  0.0  17716  1452 ?        S<s  10:35   0:00  \_ /bin/bash
20058     3989  0.0  0.0  19240  1728 ?        S<   10:35   0:00      \_ /bin/bash other_args
20058     3996  0.2  1.5 1621804 546104 ?      S<l  10:35   0:54          \_ /bin/child_process

상위 프로세스가 항상 3개 수준 떨어져 있는 것은 아닙니다. pid 3996또는 명령을 제공 /bin/child_process하고 종료할 수 있도록 명령을 사용하여 이를 자동화하는 방법이 있습니까 /bin/parent_process foobar? 특히, 항상 말하지만 /bin/parent_process매번 다른 매개변수를 사용합니다. 특정 상위 프로세스를 식별하기 위해 foobar의 출력을 ps auxf계층 구조로 탐색하기가 어렵습니다.

답변1

맨페이지 에서 proc(강조):

/proc/[pid]/stat
          Status information about the process.  This is  used  by  ps(1).
          It is defined in /usr/src/linux/fs/proc/array.c.

          pid %d      The process ID.

          The  fields,  in order, with their proper scanf(3) format speci‐
          fiers, are:

          comm %s     The filename  of  the  executable,  in  parentheses.
                      This  is  visible  whether  or not the executable is
                      swapped out.

          state %c    One character from the string "RSDZTW"  where  R  is
                      running,  S  is sleeping in an interruptible wait, D
                      is waiting in uninterruptible disk sleep, Z is  zom‐
                      bie,  T is traced or stopped (on a signal), and W is
                      paging.

 ----->   ppid %d     The PID of the parent. <--------
          ...

따라서 원하는 것은 /proc/<pid>/statPPID(상위 프로세스 ID)를 구문 분석한 다음 구문 분석하여 /proc/<ppid>/stat수행할 수 있습니다.그것은PPID 등의 방식으로 PPID 1이 발견될 때까지 계속됩니다.

기존 명령줄은 에서 찾을 수 있습니다 /proc/<ancestor_pid>/cmdline.

노트:

이 방법과 pstreeicyrock.com에서 언급한 방법은 모두 *nix에 proc파일 시스템이 있다고 가정하지만 항상 그렇지 않을 수도 있습니다. 이제 그런 기능이 있으므로 ps시스템이 이를 지원한다고 안전하게 가정할 수 있습니다 procfs.

편집하다:

다음은 위의 메소드를 구현하는 bash 스니펫입니다( pid다른 곳에서 초기화되었다고 가정).

#Initialize ppid to any value (except 1) to start the loop:
ppid=2
while [[ $ppid -ne 1 ]]
do
    ppid=$(cut -d' ' -f4 /proc/${pid}/stat)
    if [[ $ppid -eq 1 ]]
    then
        cat /proc/${pid}/cmdline
    fi
    pid=$ppid
done

답변2

당신은 그것을 사용할 수 있습니다 pstree. 예를 들어 현재 다음이 있습니다.

$ pstree -ps 2404
init(1)───lightdm(1911)───lightdm(2293)───sh(2331)───xfce4-session(2395)───{xfce4-session}(2404)

여기서 pid 2404는 귀하와 유사 /bin/child_process하고 pid 1911은 귀하와 유사합니다 /bin/parent_process foobar. 다음을 사용하여 계층 구조를 쉽게 얻을 수 있습니다.

$ pstree -ps 2404|sed 's/---/\n/g'
init(1)
lightdm(1911)
lightdm(2293)
sh(2331)
xfce4-session(2395)
{xfce4-session}(2404)

그런 다음 특정 상위 프로세스만 원하는 경우 grep을 수행할 수 있습니다.

$ pstree -ps 2404|sed 's/---/\n/g'|grep lightdm
lightdm(1911)
lightdm(2293)

귀하의 경우 프로세스가 하나만 있다는 것을 암시하는 것 같으므로 항목이 하나만 있어야 합니다(예: 위 예에서는 pid 1911만). 그런 다음 명령줄을 얻으려면 다음을 수행할 수 있습니다.

$ pstree -ps 2404|sed 's/---/\n/g'|grep lightdm|head -n1|sed 's/.*(\([0-9]\+\))/\1/'|xargs ps -o pid,args
  PID COMMAND
 1911 lightdm

내 경우에는 어떤 매개변수도 사용하지 않았지만 예를 들어 계층 구조에서 다른 PID를 사용하면 다음과 같습니다.

$ pstree -ps 2404|sed 's/---/\n/g'|grep sh|head -n1|sed 's/.*(\([0-9]\+\))/\1/'|xargs ps -o pid,args
  PID COMMAND
 2331 /bin/sh /etc/xdg/xfce4/xinitrc -- /etc/X11/xinit/xserverrc

관련 정보