Como posso automatizar esta tarefa manual de encontrar um processo ancestral particular a partir de um dado pid ou comando?

2

Eu sei o comando completo "/ bin / child_process" ou seu pid (3996 neste caso) e estou executando ps auxf e identificando visualmente seu processo ancestral /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

O processo ancestral pode nem sempre estar a 3 níveis de distância. Existe uma maneira eu posso automatizar isso com um comando de modo que eu poderia fornecer apenas o pid 3996 ou o comando /bin/child_process e sair /bin/parent_process foobar ? Em particular, ele sempre dirá /bin/parent_process , mas terá um argumento diferente de foobar a cada vez. A saída de ps auxf é muito difícil de percorrer como uma hierarquia para determinar um processo ancestral específico.

    
por Mark Rushakoff 07.07.2013 / 19:35

2 respostas

2

Na coluna proc (ênfase minha):

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

Então, o que você deseja provavelmente pode ser feito analisando /proc/<pid>/stat para o PPID (ID do processo pai) e, em seguida, analisando /proc/<ppid>/stat para o seu PPID e assim por diante até encontrar um PPID de 1 .

A linha de comando do ancestral pode ser encontrada em /proc/<ancestor_pid>/cmdline .

Nota:

Este método e o método pstree mencionado pelo icyrock.com presumem que seu * nix tem um sistema de arquivos proc , o que nem sempre é o caso. Como você já tem ps , é seguro assumir que seu sistema suporta procfs .

Editar:

Este é um snippet do bash que implementará o método acima (assume que pid foi inicializado em outro lugar):

#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
    
por 07.07.2013 / 21:16
1

Você pode usar pstree . Por exemplo. Eu tenho isso atualmente:

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

em que pid 2404 é análogo ao seu /bin/child_process e, e. pid 1911 é análogo ao seu /bin/parent_process foobar . Você pode obter a hierarquia facilmente com isso:

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

e, em seguida, se você quiser apenas um processo pai específico, você pode grep para isso:

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

No seu caso, você parece implicar que terá apenas um processo, portanto, você deve ter apenas uma entrada (por exemplo, apenas pid 1911 no meu exemplo acima). Então, se você quiser obter a linha de comando, você pode fazer algo assim:

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

No meu caso, não tem nenhum parâmetro, mas por exemplo tomar um pid diferente na hierarquia faz:

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

Espero que isso ajude.

    
por 07.07.2013 / 21:16

Tags