我正在编写一个 bash 脚本来dwm
使用xsetroot
.一切都按预期进行。我目前缺少的是一种简单的方法,只需使用标准*nix
工具即可为我提供系统上每个核心的当前负载(我有 4 个核心)。我不知道如何做到这一点,例如使用top
.到目前为止,我在该网站上找到的所有其他帖子都只处理平均负载。以前有人这样做过吗?
我希望每个核心都使用它的主要原因是拥有一个廉价且粗糙的工具来检查程序是否正在运行我并行编写的某些代码(例如,每个循环)。
答案1
这将创建一个 bash 数组,其元素是每个 CPU 的负载:
loads=($(mpstat -P ALL 1 1 | awk '/Average:/ && $2 ~ /[0-9]/ {print $3}'))
由于 bash 数组从零开始编号,因此第二个 CPU 的负载将打印为:
echo ${loads[1]}
这需要实用程序mpstat
。要将其安装在类似 Debian 的系统上,请运行:
apt-get install sysstat
怎么运行的
产生的有点冗长的输出mpstat
如下所示:
$ mpstat -P ALL 1 1
Linux 3.2.0-4-amd64 (MyMachine) 08/30/2014 _x86_64_ (2 CPU)
10:12:35 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
10:12:36 PM all 1.49 0.00 1.49 0.00 0.00 0.00 0.00 0.00 97.01
10:12:36 PM 0 0.00 0.00 2.02 0.00 0.00 0.00 0.00 0.00 97.98
10:12:36 PM 1 1.96 0.00 1.96 0.00 0.00 0.00 0.00 0.00 96.08
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
Average: all 1.49 0.00 1.49 0.00 0.00 0.00 0.00 0.00 97.01
Average: 0 0.00 0.00 2.02 0.00 0.00 0.00 0.00 0.00 97.98
Average: 1 1.96 0.00 1.96 0.00 0.00 0.00 0.00 0.00 96.08
其中-P ALL
告诉mpstat
显示所有 cpu,参数1 1
告诉它每秒打印输出并在第一秒后停止。
要仅选择我们想要的值,awk
请使用以下命令:
awk '/Average:/ && $2 ~ /[0-9]/ {print $3}'
这仅选择最后几行(以 and 开头的行Average:
,其中仅选择第二列为数字的行。对于这些行,将打印第三列(cpu 负载)。
由于使用了括号,mpstat
-awk
管道的输出被捕获到 bash 数组中。
答案2
计算每个核心的平均使用率/proc/stat
到目前为止我提出的最佳解决方案用于bc
计算浮点运算:
# Calculate average cpu usage per core.
# user nice system idle iowait irq softirq steal guest guest_nice
# cpu0 30404 2382 6277 554768 6061 0 19 0 0 0
A=($(sed -n '2,5p' /proc/stat))
# user + nice + system + idle
B0=$((${A[1]} + ${A[2]} + ${A[3]} + ${A[4]}))
B1=$((${A[12]} + ${A[13]} + ${A[14]} + ${A[15]}))
B2=$((${A[23]} + ${A[24]} + ${A[25]} + ${A[26]}))
B3=$((${A[34]} + ${A[35]} + ${A[36]} + ${A[37]}))
sleep 2
# user + nice + system + idle
C=($(sed -n '2,5p' /proc/stat))
D0=$((${C[1]} + ${C[2]} + ${C[3]} + ${C[4]}))
D1=$((${C[12]} + ${C[13]} + ${C[14]} + ${C[15]}))
D2=$((${C[23]} + ${C[24]} + ${C[25]} + ${C[26]}))
D3=$((${C[34]} + ${C[35]} + ${C[36]} + ${C[37]}))
# cpu usage per core
E0=$(echo "scale=1; (100 * ($B0 - $D0 - ${A[4]} + ${C[4]}) / ($B0 - $D0))" | bc)
E1=$(echo "scale=1; (100 * ($B1 - $D1 - ${A[15]} + ${C[15]}) / ($B1 - $D1))" | bc)
E2=$(echo "scale=1; (100 * ($B2 - $D2 - ${A[26]} + ${C[26]}) / ($B2 - $D2))" | bc)
E3=$(echo "scale=1; (100 * ($B3 - $D3 - ${A[37]} + ${C[37]}) / ($B3 - $D3))" | bc)
echo $E0
echo $E1
echo $E2
echo $E3
每个核心的平均 CPU 使用率可以直接计算得出/proc/stat
(感谢 @mikeserv 的使用提示/proc/stat
。):
# Here we make use of bash direct array assignment
A0=($(sed '2q;d' /proc/stat))
A1=($(sed '3q;d' /proc/stat))
A2=($(sed '4q;d' /proc/stat))
A3=($(sed '5q;d' /proc/stat))
# user + nice + system + idle
B0=$((${A0[1]} + ${A0[2]} + ${A0[3]} + ${A0[4]}))
B1=$((${A1[1]} + ${A1[2]} + ${A1[3]} + ${A1[4]}))
B2=$((${A2[1]} + ${A2[2]} + ${A2[3]} + ${A2[4]}))
B3=$((${A3[1]} + ${A3[2]} + ${A3[3]} + ${A3[4]}))
sleep 0.2
C0=($(sed '2q;d' /proc/stat))
C1=($(sed '3q;d' /proc/stat))
C2=($(sed '4q;d' /proc/stat))
C3=($(sed '5q;d' /proc/stat))
# user + nice + system + idle
D0=$((${C0[1]} + ${C0[2]} + ${C0[3]} + ${C0[4]}))
D1=$((${C1[1]} + ${C1[2]} + ${C1[3]} + ${C1[4]}))
D2=$((${C2[1]} + ${C2[2]} + ${C2[3]} + ${C2[4]}))
D3=$((${C3[1]} + ${C3[2]} + ${C3[3]} + ${C3[4]}))
# cpu usage per core
E0=$(((100 * (B0 - D0 - ${A0[4]} + ${C0[4]})) / (B0 - D0)))
E1=$(((100 * (B1 - D1 - ${A1[4]} + ${C1[4]})) / (B1 - D1)))
E2=$(((100 * (B2 - D2 - ${A2[4]} + ${C2[4]})) / (B2 - D2)))
E3=$(((100 * (B3 - D3 - ${A3[4]} + ${C3[4]})) / (B3 - D3)))
echo $E0
echo $E1
echo $E2
echo $E3
或者通过广泛使用 bash 直接数组赋值来缩短:
# Here we make use of bash direct array assignment by assigning line
# 2 to 4 to one array
A=($(sed -n '2,5p' /proc/stat))
# user + nice + system + idle
B0=$((${A[1]} + ${A[2]} + ${A[3]} + ${A[4]}))
B1=$((${A[12]} + ${A[13]} + ${A[14]} + ${A[15]}))
B2=$((${A[23]} + ${A[24]} + ${A[25]} + ${A[26]}))
B3=$((${A[34]} + ${A[35]} + ${A[36]} + ${A[37]}))
sleep 0.2
# user + nice + system + idle
C=($(sed -n '2,5p' /proc/stat))
D0=$((${C[1]} + ${C[2]} + ${C[3]} + ${C[4]}))
D1=$((${C[12]} + ${C[13]} + ${C[14]} + ${C[15]}))
D2=$((${C[23]} + ${C[24]} + ${C[25]} + ${C[26]}))
D3=$((${C[34]} + ${C[35]} + ${C[36]} + ${C[37]}))
# cpu usage per core
E0=$((100 * (B0 - D0 - ${A[4]} + ${C[4]}) / (B0 - D0)))
E1=$((100 * (B1 - D1 - ${A[15]} + ${C[15]}) / (B1 - D1)))
E2=$((100 * (B2 - D2 - ${A[26]} + ${C[26]}) / (B2 - D2)))
E3=$((100 * (B3 - D3 - ${A[37]} + ${C[37]}) / (B3 - D3)))
echo $E0
echo $E1
echo $E2
echo $E3
top
基于解决方案
这也可以在不安装额外工具的情况下实现top
(我在后面的文章中使用了这个)邮政.) 默认情况下,top
仅在启动时显示平均 cpu 负载,但当您按 时,它将显示所有 cpu 1
。为了能够top
在批处理输出模式下使用 cpu 输出,我们需要将其设置为top
启动时的默认行为。这可以通过使用文件来完成~/.toprc
。幸运的是,这可以自动创建:开始top
按下1
并按下W
,这将~/.toprc
在您的主文件夹中生成文件。当您现在运行时,top -bn 1 | grep -F '%Cpu'
您将看到top
现在输出所有核心。现在我们已经拥有了完成这项工作所需的一切。我需要的所有信息都在3
将作为 的输出的数组列中top
。
只有一个问题:当某个核心的 cpu 使用率达到100%
命令输出的数组时,会将具有当前负载的列从一个列移动到3
另一个列2
。因此,awk '{print $3}'
您将看到us,
column 的输出3
。如果你对此没意见,那就离开吧。如果没有,您也可以有awk
打印栏。2
就这样吧:
。避免所有这些陷阱的解决方案是:
top -bn 2 | grep -F '%Cpu' | tail -n 4 | gawk '{print $2 $3}' | tr -s '\n\:\,[:alpha:]' ' '
它会去除所有换行符和字母的输出\n
,并删除除一个空格之外的所有内容。,
[:alpha:]
-s
答案3
我想出了这个解决方案,它对我有用。
echo print `top -n 1 | tr -s " " | cut -d$" " -f10 | tail -n +8 | head -n -1 | paste -sd+ | bc`/ `nproc` | python
来源(写): https://mohammadg.com/programming/how-to-get-overall-cpu-utilization-from-the-bash-command-line/
答案4
您可以使用以下命令查看每个核心的频率:
$ cat /proc/cpuinfo