애플리케이션별 메모리/CPU 사용량 가져오기

애플리케이션별 메모리/CPU 사용량 가져오기

내가 필요한 것

프로세스뿐만 아니라 애플리케이션별로 시스템 리소스(즉, 메모리 및 CPU 사용량)를 모니터링하고 싶습니다. Windows 작업 관리자가 "호출하는 마더 프로세스"별로 리소스를 그룹화하는 것처럼 나도 그렇게 보고 싶습니다. 요즘에는 Firefox 및 vscode와 같은 애플리케이션이 많은 하위 프로세스를 생성하므로 해당 애플리케이션의 사용법에 대한 빠르고 완전한 개요를 얻고 싶습니다.

솔루션은 GUI 또는 TUI, bash 스크립트 또는 큰 단일 라이너가 될 수 있습니다. 나는 별로 상관하지 않는다. 이것이 작동하려면 필터링 수단으로 마더 프로세스의 pid나 실행 파일 이름을 제공할 수 있을 것 같습니다.

작업 관리자는 Chrome 브라우저 시스템 리소스를 그룹화/축적합니다.

내가 시도한 것

  • 시도했지만 htop호출 프로세스가 호출한 프로세스가 아닌 자체 메모리가 나열되어 있는 트리만 표시됩니다.
  • 를 시도해 보았지만 gnome-system-monitor동일합니다.
  • 나는 조금 시도했지만 ps내가 free원하는 것을 수행하도록 하는 올바른 인수/파이프 세트를 찾지 못했습니다.

Google에서 이에 대한 해결책을 찾을 수 없다는 사실이 저를 당황하게 했습니다. 아마도 이유가 있을 것 같은데요?

누구든지 아이디어가 있나요? 정말 감사하겠습니다!

답변1

아래 스크립트는 추가적인 개선이 많이 필요하지만, 기초로 삼을 수 있을 것 같습니다.
댓글을 쓰기 시작했는데 지금은 끝낼 수 없습니다. 더 많은 여유 시간이 생기면 내 답변에 대한 편집 내용을 사용하여 새로운 댓글을 추가하고 버그를 수정하겠습니다.
내 환경에서는 잘 작동합니다. 나는 이 스크립트를 mytop이라고 부르고 /usr/local/bin에 넣어서 bash 명령 탭 완성 기능을 갖게 했습니다. mytop을 ~/bin 디렉토리($PATH에 ~/bin이 없으면 추가)나 컴퓨터의 어느 위치에나 넣을 수 있습니다. 물론 실행 비트는 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

관련 정보