Reputation: 14697
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
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
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
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