用於評估 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
並通過對、nice
、system
、求和來評估使用的 CPU 時間,並通過對irq
、softirq
求和來評估steal
CPU 空閒時間。然後我將使用的 CPU 時間 + CPU 空閒時間相加以獲得總 CPU 時間並將 CPU 使用時間除以總 CPU 時間。idle``iowait
這種方法的問題在於,這是自系統上次啟動以來的平均 CPU 使用率。為了獲得目前使用情況,我需要檢查兩次
/proc/stat
並使用兩次檢查之間的總 CPU 時間和已用 CPU 時間之間的差異,然後將結果除以它們之間的時間差異(以秒為單位)。為此,我使用了一個while
無限循環和一個 sleep 命令。我希望輸出格式如下: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
僅在腳本的整個持續時間內使用一行?
我認為您希望
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
變數。它在每次列印後遞增,以通知使用者舊行被螢幕上的新行替換。我還替換了你的電話
echo
,printf
因為它更便攜。