2

What I need

I want to monitor system resources (namely memory and cpu usage) by application - not just by process. Just as the Windows Task Manager is grouping resources by the "calling mother process", I like to see it like that as well. Nowadays, applications like firefox and vscode spawn many child processes and I want to get a quick and complete overview of their usage.

The solution can be a GUI or TUI, a bash script or a big one-liner. I do not really care. For it to work, I imagine I could feed it with the pid of the mother process or the name of an executable as a means of filtering.

Example

Task Manager groupes/accumulates Chrome browser system resources

What I Tried

  • I tried htop, but it only shows me a tree where the calling process has its own memory listed - not the ones it called.
  • I tried the gnome-system-monitor, but its the same.
  • I tried a bit with ps and free but have not found the correct set of arguments / pipes to make them do what I want.

It stumped me that I could not google a solution for that. Maybe there is a reason for it?

Does anybody have an idea? I would very much appreciate it!

1
  • No solutions. You could write and submit patches for htop/top. Oct 25 '21 at 13:06
1

This script below requires a lot of additional improvements, but I think it can serve as a basis.
I started to write comments, but for now, not able to finish it. I will use edits to my answer to add new comments and fix bugs when I get more free time.
In my environment it works fine. I called this script mytop and put it to /usr/local/bin so I have bash command tab completion on it. You can put mytop to your ~/bin directory (if ~/bin not in your $PATH, add it), or whatever place on your machine. Of course execute bit must be set, with chmod u+x mytop.

#!/bin/bash
# mytop -ver 1.0

# script name (default is: 'mytop')
s_name=$(basename $0)

# version
ver="1.0"

# set default time between mytop iterations
sec_delay=3 
# set default mytop repetitions/iterations
mt_rep=1000000

# Help function explaining syntax, options, ...
Help()
{
# Display Help
echo
echo "Show Totals of %CPU and &MEM using 'top' command."
echo
echo "Syntax:"
echo "   $s_name [-h|-V]"
echo "   $s_name [[-d <S>][-n <N>] <APP_NAME>"]
echo 
echo "Options:"
echo "     -h       Print this Help."
echo "     -d S     Delay/wait S seconds between iterations (default: 3 seconds)."
echo "     -n N     Run/iterate 'mytop' N times (default: 3 times)."
echo "     -V       Print version."
echo
echo "Examples:"
echo "   mytop -V"
echo "   mytop -d1 -n5 chromium"
echo
echo 'Use CTRL+C for exit!'
echo
}

# Handling options from command line arguments
while getopts ":hn:d:V" option; do
case $option in
  h) # display Help
     Help
     exit;;
  V) # print version 
     echo "$s_name $ver"
     exit;;
  n) # set how many times 'mytop' will repeat/iterate
     mt_rep=$OPTARG;;
  d) # set delays in seconds
     sec_delay=$OPTARG;;
 \?)
     echo "$s_name: inapropriate: '$1'."
     echo "Usage:"
     echo "  $s_name [-h|-V|-d<S> -n<N> <APP_NAME>]"
     exit;;
  esac
done

# If no arguments given just display Help function and exit
if [[ $# -eq 0 ]]; then
    Help
    exit
else
    # If last argument starts with '-' exit from app
    if [[ ${@:$#} =~ -+.* ]]; then
        echo ${s_name}: error: Last argument must be the name of the application that you want to track. >&2
        exit 1
    else
        app_name=${@:$#}
    fi
fi



# Set 'dashes' literally
#t_dsh='-----------------------------------------------------------'
# or set them with printf command
t_dsh=$(printf '%0.s-' {1..59})

# Not in use
#if [[ -z $mt_rep ]] 2>/dev/null; then
#   r_endless=1
#   mt_rep=1000
#else
#   r_endless=0
#fi



i=0
while [[ $i -lt $mt_rep ]]; do

    #if [[ "$r_endless" == "0" ]]; then ((i++)); fi
    ((i++))

    # Handle pids of app you want to track by removing 'mytop' pids
    # get s_name (mytop) pids
    pgrep $s_name > /tmp/mt_pids
    # get app_name pids -all of them --not desired behaviour
    pgrep -f $app_name > /tmp/app_name_pids
    # get app_name without mytop pids --desired behaviour
    for e in $(cat /tmp/mt_pids); do sed -i "/$e/d" /tmp/app_name_pids; done
    if [[ ! -s "/tmp/app_name_pids" ]]; then echo "1000000" > /tmp/app_name_pids; fi

    # top -b -n1 -p; -b for output without ANSI formating; -n1 for just one iteration of 'top'; -p for feeding processes from 'pgrep' command
    # Use LC_NUMERIC if your 'top' command outputs 'commas' instead 'dots' - with LC_NUMERIC you will get 'dots' during this script
    LC_NUMERIC=en_US.UTF-8 top -b -n1 -p $(cat /tmp/app_name_pids | xargs | tr ' ' ,) > /tmp/pstemp

    wc_l=$(wc -l < /tmp/pstemp)

    cpu_use=$(tail -n +8 /tmp/pstemp | tr -s ' ' | sed 's/^ *//' | cut -d' ' -f9 | xargs | tr ' ' + | bc)
    if [[ "$cpu_use" == "0" ]]; then
        cpu_use="0.0"
    else
        if (( $(bc <<< "$cpu_use < 1") )); then cpu_use="0$cpu_use"; fi
    fi

    mem_use=$(tail -n +8 /tmp/pstemp | tr -s ' ' | sed 's/^ *//' | cut -d' ' -f10 | xargs | tr ' ' + | bc)
    if [[ "$mem_use" == "0" ]]; then
        mem_use="0.0"
    else
        if (( $(bc <<< "$mem_use < 1") )); then mem_use="0$mem_use"; fi
    fi

    echo -en "\033[2J\033[0;0f"
    # Use 'echo ...' above or 'tput ...' below (chose the one that works for you)
    #tput cup 0 0 && tput ed

    # Align Totals under %CPU and %MEM columns
    if (( $(bc <<< "$cpu_use < 1") )); then
        sed "${wc_l}a \\\n\nTotal (%CPU/%MEM): $(printf " %29s")$cpu_use  $mem_use\n${t_dsh}" /tmp/pstemp
    elif (( $(bc <<< "$cpu_use < 100") )); then
        sed "${wc_l}a \\\n\nTotal (%CPU/%MEM): $(printf " %28s")$cpu_use  $mem_use\n${t_dsh}" /tmp/pstemp
    else
        sed "${wc_l}a \\\n\nTotal (%CPU/%MEM): $(printf " %27s")$cpu_use  $mem_use\n${t_dsh}" /tmp/pstemp
    fi  

    if [[ $i -lt $mt_rep ]]; then sleep $sec_delay; fi
done
2
  • 1
    I am stomped that there is no common solution for this problem and/or nobody else is looking for this. But I am even more amazed by the beautiful and very helpful script you wrote. It perfectly addresses what I was looking for and I will use this very often. Thank you very much!
    – Y. Shallow
    Nov 1 '21 at 13:22
  • You are welcome. I'm very glad that you found this script useful for you. When time allows I will change/add some things... I appreciate your comment/feedback.
    – Damir
    Nov 3 '21 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.