Linux
按應用程序獲取記憶體/cpu 使用情況
我需要的
我想按應用程序監視系統資源(即記憶體和 cpu 使用情況)——而不僅僅是按程序。正如 Windows 任務管理器按“呼叫母程序”對資源進行分組一樣,我也喜歡這樣看。如今,像 firefox 和 vscode 這樣的應用程序產生了許多子程序,我想快速完整地了解它們的使用情況。
解決方案可以是 GUI 或 TUI、bash 腳本或大型單線。我真的不在乎。為了讓它工作,我想我可以用母程序的 pid 或執行檔的名稱來提供它作為過濾手段。
例子
我試過的
- 我試過
htop
了,但它只顯示了一棵樹,其中呼叫程序列出了自己的記憶體 - 而不是它呼叫的記憶體。- 我試過了
gnome-system-monitor
,但它是一樣的。- 我嘗試了一下,
ps
但free
沒有找到正確的參數/管道集來讓它們做我想做的事。這讓我很難過,我無法通過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