2

I know the full command "/bin/child_process" or its pid (3996 in this case) and I'm running ps auxf and then visually identifying its ancestor process /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

The ancestor process may not always be 3 levels away. Is there a way I can automate this with a command such that I could supply just the pid 3996 or the command /bin/child_process and get out /bin/parent_process foobar? In particular, it will always say /bin/parent_process, but it will have a different argument than foobar every time. The output of ps auxf is very difficult to traverse as a hierarchy to determine a particular ancestor process.

2

From the proc manpage (emphasis mine):

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

So what you want can probably be accomplished by parsing /proc/<pid>/stat for the PPID (parent process ID) and then parsing /proc/<ppid>/stat for its PPID and so on until you find a PPID of 1.

The ancestor's command line can be found in /proc/<ancestor_pid>/cmdline.

Note:

Both this method and the pstree method mentioned by icyrock.com assume that your *nix has a proc filesystem which may not always be the case. Since you already have ps, it's safe to assume your system supports procfs.

Edit:

Here's a bash snippet that will implement the above method (assumes pid has been initialized elsewhere):

#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
1

You can use pstree. E.g. I have this currently:

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

where pid 2404 is analogous to your /bin/child_process and e.g. pid 1911 is analogous to your /bin/parent_process foobar. You can get the hierarchy easily with this:

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

and then if you want only a specific parent process, you can grep for that:

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

In your case, you seem to imply you'll have only one process, so you should have only one entry (e.g. only pid 1911 in my example above). Then if you want to get the command line, you can do something like this:

$ 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

In my case, it did not have any params, but e.g. taking a different pid in the hierarchy does:

$ 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.