Walking a process tree

linux, pstree, shell, unix

Solution

Just wanted to document my steps related to this problem.

Say I execute this in a terminal:

~$ echo "read -p 'Press Enter'" > mytest.sh
~$ chmod +x mytest.sh
~$ bash -c bash
~$ bash -c ./mytest.sh

... and leave it waiting at the `read` input prompt. Then, I can always find the pid of `mytest.sh` like:

$ ps axf | grep mytest
20473 pts/2    S+     0:00              |   |   \_ grep --color=tty mytest
20308 pts/5    S+     0:00              |   |       \_ bash -c ./mytest.sh

... however, I'd like to output a `ps axf` tree limited to some parent of `mytest.sh`; looking at a full `ps axf`, we can see a hierarchy:

$ ps axf

 1489 ?        Sl     1:39              \_ gnome-terminal --sm-client-id 106ab86
 1511 ?        S      0:00              |   \_ gnome-pty-helper
...
20238 pts/5    Ss     0:00              |   \_ bash
20274 pts/5    S      0:00              |   |   \_ bash
20308 pts/5    S+     0:00              |   |       \_ bash -c ./mytest.sh
...

Then, say I don't want to 'scan' the `gnome-terminal` (1489) as parent, but instead I want to start at `bash` (20238).. So, I'd like to obtain this output:

$ ps f -p 20238 20274 20308
  PID TTY      STAT   TIME COMMAND
20238 pts/5    Ss     0:00 bash
20274 pts/5    S      0:00  \_ bash
20308 pts/5    S+     0:00      \_ bash -c ./mytest.sh

... except, I don't want to copy/paste the child PIDs manually :)

I could use `pstree`:

$ pstree -a -p 20238
bash,20238
  └─bash,20274
      └─bash,20308 -c ./mytest.sh

$ pstree -p 20238
bash(20238)───bash(20274)───bash(20308)

... unfortunately, the output is not exactly the same as in `ps axf`, which I prefer.

So, I can use `pstree` simply to obtain child PIDs:

$ pstree -p 20238 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/'
20238
20274
20308

$ pstree -p 20238 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" ,
20238,20274,20308,

and then use those to obtain a `ps axf` tree, based only on the PID of the parent:

$ ps f -p $(pstree -p 20238 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " ")
  PID TTY      STAT   TIME COMMAND
20238 pts/5    Ss     0:00 bash
20274 pts/5    S      0:00  \_ bash
20308 pts/5    S+     0:00      \_ bash -c ./mytest.sh

Well, hope this helps someone, Cheers!

Problem

I have the following scenario. The user would type the PID of a process, and the script should show the process and it's subprocesses, sub-subprocesses (and so on) of PID, and it should list it in a tree format. I tried using `pstree PID` and `ps faux PID`, but it doesn't work. It seems like it doesn't take PID of processes as arguments. Any ideas please?

Original source