Walking a process tree

前端 未结 3 1617
独厮守ぢ
独厮守ぢ 2020-12-24 10:28

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)

相关标签:
3条回答
  • 2020-12-24 10:35

    This is the bash script using only ps and awk. You can use at as a base for generating process tree.

    ppid=$1
    while true
    do 
        forloop=FALSE
        # get all children by pid 
        for i in `ps -ef | awk '$3 == '$ppid' {print $2}'`
        do 
           # Here you have one of of the elements of tree 
           #   parent -> child
           echo $ppid - $i 
           forloop=TRUE
        done
        ppid=$i
    
        if [ "$forloop" = "FALSE" ]; then
           exit
        fi
     done
    
    0 讨论(0)
  • 2020-12-24 10:38

    Your first step is to pipe ps through awk and grep. By using awk, you can isolate either the 'this process PID' field or the 'parent process PID' field.

    Or, have a stroll through the /proc file system.

    0 讨论(0)
  • 2020-12-24 10:50

    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!

    0 讨论(0)
提交回复
热议问题