CPU 사용량을 추정하기 위한 Bash 스크립트

CPU 사용량을 추정하기 위한 Bash 스크립트

모든 코어 목록과 현재 로드를 터미널에 평가하고 표시하는 BASH 스크립트를 작성하려고 합니다. 내가 사용하고 있는 출력은 /proc/stat. 예를 들어:

cat /proc/stat
     user nice system idle iowait  irq  softirq steal guest guest_nice
cpu  4705 356  584    3699   23    23     0       0     0          0

user그리고 CPU 사용 시간은 , , 를 합산하여 평가하고 nice, systemCPU 유휴 시간은 합산하여 평가합니다. 그런 다음 사용된 CPU 시간 + CPU 유휴 시간을 더해 총 CPU 시간을 구하고 CPU 사용 시간을 총 CPU 시간으로 나눴습니다.irqsoftirqstealidleiowait

이 접근 방식의 문제점은 이것이 시스템이 마지막으로 부팅된 이후의 평균 CPU 사용량이라는 것입니다. 현재 사용량을 얻으려면 두 번 확인 /proc/stat하고 두 확인 사이의 총 CPU 시간과 사용된 CPU 시간의 차이를 사용한 다음 결과를 초 단위의 시간 차이로 나누어야 합니다. 이를 위해 while무한 루프와 절전 명령을 사용합니다. 다음 형식으로 출력하고 싶습니다.

CPU: 10%
CPU0: 15%
CPU1: 5%
CPU2: 7%
CPU3: 13%

모든 코어의 총 CPU 사용량과 각 코어의 CPU 사용량이 각 절전 모드 후에 자동으로 업데이트되기를 원합니다. 이것은 지금까지 내 코드입니다.

#!/bin/bash

PREV_CPU_USE=0
PREV_CPU_IDLE=0
PREV_EPOCH_TIME=0

# Setting the delimiter
IFS=$'\n'

while true; do
  # Getting the total CPU usage
  CPU_USAGE=$(head -n 1 /proc/stat)

  # Getting the Linux Epoch time in seconds
  EPOCH_TIME=$(date +%s)

  # Splitting the /proc/stat output
  IFS=" " read -ra USAGE_ARRAY <<< "$CPU_USAGE"

  # Calculating the used CPU time, CPU idle time and CPU total time
  CPU_USE=$((USAGE_ARRAY[1] + USAGE_ARRAY[2] + USAGE_ARRAY[3] + USAGE_ARRAY[6] + USAGE_ARRAY[7] + USAGE_ARRAY[8] ))
  CPU_IDLE=$((USAGE_ARRAY[4] + USAGE_ARRAY[5]))

  # Calculating the differences
  DIFF_USE=$((CPU_USE - PREV_CPU_USE))
  DIFF_IDLE=$((CPU_IDLE - PREV_CPU_IDLE))
  DIFF_TOTAL=$((DIFF_USE + DIFF_IDLE))
  DIFF_TIME=$((EPOCH_TIME - PREV_EPOCH_TIME))

  #Printing the line and ommiting the trailing new line and using carrier trailer to go to the beginning of the line
  echo -en "${USAGE_ARRAY[0]} Usage: $((DIFF_USE*100/(DIFF_TOTAL*DIFF_TIME)))%                          \\r\\n"
  echo -en "${USAGE_ARRAY[0]} Idle: $((DIFF_IDLE*100/(DIFF_TOTAL*DIFF_TIME)))%                         \\r"

  # Assigning the old values to the PREV_* values
  PREV_CPU_USE=$CPU_USE
  PREV_CPU_IDLE=$CPU_IDLE
  PREV_EPOCH_TIME=$EPOCH_TIME

  # Sleep for one second 
  sleep 1
done

여기에서는 스크립트를 단순화하고 실제로 현재 CPU 사용량과 유휴 CPU 시간을 서로 다른 두 줄에 인쇄합니다. 하지만 cpu Idle한 줄에 있어도 cpu Usage다음과 같이 새 줄이 추가됩니다.

cpu Usage: 0%                         
cpu Usage: 0%                         
cpu Usage: 0%                         
cpu Idle: 99%

cpu Usage스크립트 전체 기간 동안 한 줄에만 표시 할 수 있는 옵션이 있습니까 ?

답변1

나는 cpu Usage문자열이 매번 같은 줄 바로 다음 cpu Idle줄에 나타나기를 원한다고 생각합니다. 이를 달성하려면 tput( el) clr_eol터미널 기능을 사용하여 줄을 삭제하고 cuu( parm_up_cursor)를 사용하여 n 줄 위로 이동할 수 있습니다. 에서 터미널 기능에 대해 읽을 수 있습니다 man terminfo. 스크립트는 다음과 같습니다.

#!/bin/bash

PREV_CPU_USE=0
PREV_CPU_IDLE=0
PREV_EPOCH_TIME=0

# Setting the delimiter
IFS=$'\n'
counter=0

while true; do
  # Getting the total CPU usage
  CPU_USAGE=$(head -n 1 /proc/stat)

  # Getting the Linux Epoch time in seconds
  EPOCH_TIME=$(date +%s)

  # Splitting the /proc/stat output
  IFS=" " read -ra USAGE_ARRAY <<< "$CPU_USAGE"

  # Calculating the used CPU time, CPU idle time and CPU total time
  CPU_USE=$((USAGE_ARRAY[1] + USAGE_ARRAY[2] + USAGE_ARRAY[3] + USAGE_ARRAY[6] + USAGE_ARRAY[7] + USAGE_ARRAY[8] ))
  CPU_IDLE=$((USAGE_ARRAY[4] + USAGE_ARRAY[5]))

  # Calculating the differences
  DIFF_USE=$((CPU_USE - PREV_CPU_USE))
  DIFF_IDLE=$((CPU_IDLE - PREV_CPU_IDLE))
  DIFF_TOTAL=$((DIFF_USE + DIFF_IDLE))
  DIFF_TIME=$((EPOCH_TIME - PREV_EPOCH_TIME))

  printf "\r%s%s Usage: %d (counter = %d)\n" "$(tput el)" "${USAGE_ARRAY[0]}" "$((DIFF_USE*100/(DIFF_TOTAL*DIFF_TIME)))" "$counter"
  printf "\r%s%s Idle: %d (counter = %d)" "$(tput el)" "${USAGE_ARRAY[0]}" "$((DIFF_IDLE*100/(DIFF_TOTAL*DIFF_TIME)))" "$counter"
  counter=$((counter + 1))

  tput cuu 1

  # Assigning the old values to the PREV_* values
  PREV_CPU_USE=$CPU_USE
  PREV_CPU_IDLE=$CPU_IDLE
  PREV_EPOCH_TIME=$EPOCH_TIME

  # Sleep for one second 
  sleep 1
done

counter디버깅 목적으로 추가 변수를 추가했습니다 . 이전 행이 화면의 새 행으로 대체되었음을 사용자에게 알리기 위해 각 인쇄 후에 증가합니다.

echoprintf또한 휴대성이 더 좋기 때문에 귀하의 통화를 로 대체했습니다 .

관련 정보