特定の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レベル離れているわけではありません。 pid3996またはコマンドを提供し/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_processpid 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)

あなたの場合、プロセスが1つしかないことを示唆しているように見えるので、エントリは1つだけ必要です(たとえば、上記の例では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

関連情報