Display only a process subtree

Posted on

Display only a process subtree – A server stack is the collection of software that forms the operational infrastructure on a given machine. In a computing context, a stack is an ordered pile. A server stack is one type of solution stack — an ordered selection of software that makes it possible to complete a particular task. Like in this post about Display only a process subtree was one problem in server stack that need for a solution. Below are some tips in manage your linux server when you find problem about linux, command-line-interface, , , .

I would like to show a listing of a single process and its current children. So, given the following process tree:

Imagine the following process listing:

  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:00 [kthreadd]
    3 ?        S      0:06  _ [ksoftirqd/0]  
  ...snip...
 1292 ?        Ss     0:06 /usr/sbin/gpm -m /dev/input/mice -t exps2
 1426 ?        Ss     0:00 /usr/lib/postfix/master
 9785 ?        S      0:00  _ qmgr -l -t fifo -u
12301 ?        S      0:00  _ pickup -l -t fifo -u -c
 1545 ?        Ss     0:05 /usr/sbin/apache2 -k start
 1570 ?        S      0:00  _ /usr/sbin/apache2 -k start  
  ...snip...

I would like to instead just show process 1426 and its children. Like this:

  PID TTY      STAT   TIME COMMAND
 1426 ?        Ss     0:00 /usr/lib/postfix/master
 9785 ?        S      0:00  _ qmgr -l -t fifo -u
12301 ?        S      0:00  _ pickup -l -t fifo -u -c

Is there a simple way to do this?

You can use pstree to do this and get a nicely formatted output too

pstree -p 22221
mysqld_safe(22221)─┬─logger(22334)
                   └─mysqld(22332)─┬─{mysqld}(22335)
                                   ├─{mysqld}(22336)
                                   ├─{mysqld}(22337)
                                   ├─{mysqld}(22338)
                                   ├─{mysqld}(22340)
                                   ├─{mysqld}(22341)
                                   ├─{mysqld}(22342)
                                   ├─{mysqld}(22343)
                                   ├─{mysqld}(22346)
                                   └─{mysqld}(22394)

$ ps -p 1426 --ppid 1426 --forest

or:

$ ps -eo pid,ppid,tty,stat,time,command --forest | awk '$1 == 1426 || $2 == 1426'

to display the details command.

The following script displays all processes running under tmux:

#!/usr/bin/env bash
set -eu

my_pid=$$
subtree_pids() {
    local pid=$1 level=${2:-0}
    if [ "$pid" = "$my_pid" ]; then
        return
    fi
    echo "$pid"
    ps --ppid "$pid" -o pid= | while read -r pid; do
        subtree_pids "$pid" $((level + 1))
    done
}

server_pid=$(tmux display-message -pF '#{pid}')
ps -p "$(subtree_pids "$server_pid" | paste -sd,)" -Ho pid,ppid,comm,args

The output looks like this:

 7170     1   tmux: server    tmux -f /home/yuri/.tmux-windows at
 7171  7170     bash            bash --rcfile /dev/fd/63 -i
 7182  7171       vim             vim ...
 7173  7170     bash            bash --rcfile /dev/fd/63 -i
 7183  7173       vim             vim ...

For that it recursively calls ps --ppid .... my_pid stores PID of the script itself, to avoid infinite recursion. level variable is just in case you need to debug the script. = in ps -o pid= makes it to not display headers. paste -sd, turns newline-separated list into a comma-separated one (-d specifies delimiter, more on it here). tmux display-message displays server PID (-p – to stdout).

Leave a Reply

Your email address will not be published. Required fields are marked *