Linux

按應用程序獲取記憶體/cpu 使用情況

  • October 27, 2021

我需要的

我想按應用程序監視系統資源(即記憶體和 cpu 使用情況)——而不僅僅是按程序。正如 Windows 任務管理器按“呼叫母程序”對資源進行分組一樣,我也喜歡這樣看。如今,像 firefox 和 vscode 這樣的應用程序產生了許多子程序,我想快速完整地了解它們的使用情況。

解決方案可以是 GUI 或 TUI、bash 腳本或大型單線。我真的不在乎。為了讓它工作,我想我可以用母程序的 pid 或執行檔的名稱來提供它作為過濾手段。

例子

任務管理器對 Chrome 瀏覽器系統資源進行分組/積累

我試過的

  • 我試過htop了,但它只顯示了一棵樹,其中呼叫程序列出了自己的記憶體 - 而不是它呼叫的記憶體。
  • 我試過了gnome-system-monitor,但它是一樣的。
  • 我嘗試了一下,psfree沒有找到正確的參數/管道集來讓它們做我想做的事。

這讓我很難過,我無法通過Google搜尋解決方案。也許是有原因的?

有人有想法嗎?我將不勝感激!

下面的這個腳本需要很多額外的改進,但我認為它可以作為一個基礎。

我開始寫評論,但現在無法完成。當我有更多空閒時間時,我將使用對答案的編輯來添加新評論並修復錯誤。

在我的環境中它工作正常。我將此腳本稱為 mytop 並將其放到 /usr/local/bin 中,這樣我就可以完成 bash 命令選項卡了。您可以將 mytop 放到您的 ~/bin 目錄中(如果 ~/bin 不在您的 $PATH 中,請添加它),或者您機器上的任何位置。當然必須設置執行位,使用 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

引用自:https://unix.stackexchange.com/questions/674717