Ashish
Ashish

Reputation: 14697

How to fetch the pid of all children or grandchildren of a process using shell script

I have been given a task to fetch the cpu/memory utilization of the children/grandchildren of a process. Which can be found using top command. I have write down a script which will fetch the children of a process but I am not sure how can I recursively find all children and grand children of a process.

#!/bin/bash
ID=$PPID
read PID < <(exec ps -o ppid= "$ID")
for _child in $(pgrep -P "$PID"); do
    top -c -b -n 1 -p "$_child"
done

I have tried to use pstree as well but I do not wants to track light weight process. Could some one please help me how can I find the grand children of the process.

Upvotes: 0

Views: 1734

Answers (3)

sealor
sealor

Reputation: 155

You can also combine awk with ps --forest to resolve all relevant PIDs:

ps f o pid,ppid | awk -v PID=$PARENT_PID '$1 == PID || pids[$2] == 1 {pids[$1]=1}; pids[$1] == 1 {print $1}'

Upvotes: 0

konsolebox
konsolebox

Reputation: 75458

function list_children {
    [[ $2 == --add ]] || LIST=()
    local ADD=() __
    IFS=$'\n' read -ra ADD -d '' < <(exec pgrep -P "$1")
    LIST+=("${ADD[@]}")

    for __ in "${ADD[@]}"; do
        list_children "$__" --add
    done
}

Example usage:

list_children "$PPID"
echo "Children: ${LIST[*]}"

for CHILD in "${LIST[@]}"; do
    top -c -b -n 1 -p "$CHILD"
done

Upvotes: 3

Tiago Lopo
Tiago Lopo

Reputation: 7959

Doing it in a for loop is slow, try this:

grep -f <(ps o ppid,pid | awk '$1==<PID>{print $2" "}') <(top -cbn 1)

With this you only run top -cbn 1 once and get the result you need.

Example:

grep -f <(ps o ppid,pid | awk '$1==1{print $2" "}') <(top -cbn 1)
 1756 root      20   0  4096    4    0 S  0.0  0.0   0:00.00 /sbin/mingetty /dev/tty1                                                                  
 1758 root      20   0  4096    4    0 S  0.0  0.0   0:00.00 /sbin/mingetty /dev/tty2                                                                  
 1760 root      20   0  4096    4    0 S  0.0  0.0   0:00.00 /sbin/mingetty /dev/tty3                                                                  
 1762 root      20   0  4096    4    0 S  0.0  0.0   0:00.00 /sbin/mingetty /dev/tty4                                                                  
 1765 root      20   0  4108    4    0 S  0.0  0.0   0:00.00 /sbin/agetty /dev/hvc0 38400 vt100-nav                                                    
 1766 root      20   0  4096    4    0 S  0.0  0.0   0:00.00 /sbin/mingetty /dev/tty5                                                                  
 1769 root      20   0  4096    4    0 S  0.0  0.0   0:00.00 /sbin/mingetty /dev/tty6 

Update: The above command only get immediate child pid, if you need the whole tree of pids:

grep -f <(pstree -cp <pid> | grep -Po '\(\K\d+'| sed -re 's/$/ /g' | sed -re 's/^/^\\s\*/g' ) <(top -cbn 1)

Upvotes: 2

Related Questions