如何在Linux上获取总体CPU使用率(例如57%)

264
我想知道如何使用bash获取系统CPU使用率并以百分比形式呈现。
示例输出:
57%

如果有多个核心的话,计算出平均百分比会更好。


1
@julesanchez 这个值需要被传输到其他地方,因此它必须是一个整数。 - user1199739
15
一个不需要 sysstat 的命令:ps -A -o pcpu | tail -n+2 | paste -sd+ | bc - RFon
21
“重新开放”我不明白为什么这被判定为不符合主题,能否请关闭它的人详细说明一下原因? - Jonathan H
5
我对 /proc/stat 的理解非常有限,但是这个一行命令对我来说已经足够好用了:cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS="" '{printf "%.2f%\n", ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'。使用 %.2f 可以控制输出的小数点位数,而 sleep 1 可以设置你想要求平均值的时间间隔,如果它确实做到了我所认为的。你可以将它放在一个 bash while 循环中,以实时测试它。 - Yeti
现在我使用这个命令:{ head -n1 /proc/stat;sleep 0.2;head -n1 /proc/stat; } | awk '/^cpu /{u=$2-u;s=$4-s;i=$5-i;w=$6-w}END{print int(0.5+100*(u+s+w)/(u+s+i+w))}',它可以在给定的延迟时间(在本例中设置为200毫秒)内返回平均CPU百分比,以四舍五入的整数值表示(但您也可以省略 int(0.5+ 部分)。 - Yeti
显示剩余10条评论
6个回答

240
请看一下cat /proc/stat grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' 编辑提示:在复制粘贴或将此用于任何严肃的工作之前,请先阅读评论。这未经测试或使用,这是一个想法,适用于不想安装实用程序或适用于任何发行版的人。有些人认为你可以“apt-get install”任何东西。
注意:这不是当前CPU使用率,而是自系统启动以来所有核心的总体CPU使用率。这可能与当前CPU使用率非常不同。要获取当前值,必须使用top(或类似的工具)。
当前CPU使用率可能通过以下方式计算:
awk '{u=$2+$4; t=$2+$4+$5; if (NR==1){u1=u; t1=t;} else print ($2+$4-u1) * 100 / (t-t1) "%"; }' \
<(grep 'cpu ' /proc/stat) <(sleep 1;grep 'cpu ' /proc/stat)

12
但是你必须像你之前建议的那样安装mpstat。许多人没有这种灵活性。使用cat /proc/stat命令再通过管道处理比你推荐的mpstat命令更容易。 - vimdude
12
不理解为什么解析另一个实用程序要比解析/proc/stat更好。 - Reinstate Monica Please
9
系统 + 用户 + 空闲 = 100%。可能会有类似这样的表述: 在 /proc/stat 文件中查找 'cpu',并使用 awk 命令计算 CPU 的使用率,公式为 ($2+$4)*100/($2+$4+$5),最后打印出结果加上百分号。 - vimdude
122
我认为这个解决方案显示的不是当前 CPU 负载,而是自 CPU 启动以来的平均 CPU 负载。 - Etienne
12
@jlliagre,是的,没错。要计算当前 CPU 使用率而不是平均值,您需要获取 $1 值,进行延迟,然后再获取 $1 值并计算差异。这就是当前的 CPU 使用率。 - vimdude
显示剩余23条评论

127

你可以尝试:

top -bn1 | grep "Cpu(s)" | \
           sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \
           awk '{print 100 - $1"%"}'

19
每次我运行这个命令,都会得到相同的输出结果(32.7%)。 - alanaktion
16
使用 top -bn2 命令可以得到更精确的结果,但需要花费较长时间。据我所知,这似乎是获取准确结果的唯一方法。 - alanaktion
7
在我的FC20系统中,top -bn1 看起来极不准确。而 top -bn2 则表现得很好。 - Martin Tournoij
28
这个答案中的命令似乎是针对top -v返回procps-ng(例如Fedora)的系统编写的。还有procps,例如Ubuntu和CentOS上找到的,该命令无法工作(始终指示为100%,因为由于CPU数字所在的行具有不同的格式而导致解析失败)。这里是一个适用于两种实现的版本:top -b -n2 -p 1 | fgrep "Cpu(s)" | tail -1 | awk -F'id,' -v prefix="$prefix" '{ split($1, vs, ","); v=vs[length(vs)]; sub("%", "", v); printf "%s%.1f%%\n", prefix, 100 - v }' - mklement0
2
附注:在OSX上,请使用以下命令:top -l 2 -n 0 -F | egrep -o ' \d*\.\d+% idle' | tail -1 | awk -F% -v prefix="$prefix" '{ printf "%s%.1f%%\n", prefix, 100 - $1 }' - mklement0
显示剩余28条评论

42

尝试使用 sysstat 包中的 mpstat

> sudo apt-get install sysstat
Linux 3.0.0-13-generic (ws025)  02/10/2012  _x86_64_    (2 CPU)  

03:33:26 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
03:33:26 PM  all    2.39    0.04    0.19    0.34    0.00    0.01    0.00    0.00   97.03

然后使用 cutgrep 命令来解析你需要的信息:

mpstat | grep -A 5 "%idle" | tail -n 1 | awk -F " " '{print 100 -  $ 12}'a

2
我不相信这显示了总CPU。 - user1199739
我会将 awk 部分修改为:awk -F " " '{print (100 - $12)"%"}',这样输出的格式就像他想要的那样,但除此之外,我认为这看起来很好。 - Dan Fego
1
@jordanm 所有的真相;我更多是投票支持它,因为它有效。就我个人而言,我会这样做:mpstat | awk '$12 ~ /[0-9.]+/ { print 100 - $12 }' - Dan Fego
对我而言,这个命令可以运行:mpstat -P ALL | head -4 | tail -1 | awk -F " " '{print (100 - $11)"%"}' - FirstName LastName
谢谢 :) 这适用于树莓派 Jesse ( mpstat | grep -A 5 "%idle" | tail -n 1 | awk -F " " '{print 100 - $13 "%"}' ) - Rahim Khoja
显示剩余7条评论

36

我可以提供一个实际的解决方案,它受到Peter Liljenberg启发:

$ mpstat | awk '$12 ~ /[0-9.]+/ { print 100 - $12"%" }'
0.75%
这将使用 awk 打印出100减去第12个字段(空闲时间),后面跟一个百分号。awk 仅对第12个字段仅包含数字和点号的行执行此操作($12 ~ /[0-9]+/)。
您还可以平均取五个样本,每个样本相隔一秒钟:
$ mpstat 1 5 | awk 'END{print 100-$NF"%"}'

可以用以下方法进行测试:

$ mpstat 1 5 | tee /dev/tty | awk 'END{print 100-$NF"%"}'

19
最好运行命令"mpstat 2 1 |...",这样它将显示过去1秒的统计数据。否则,默认情况下,mpstat显示自开始以来的统计数据,随着时间的推移变化不大。 - Sarang
2
这个命令对我有用:mpstat | awk '$12 ~ /[0-9.]+/ { print 100 - $11"%" }' - AloneInTheDark
@Sarang非常感谢!!最终我也可以得到conky所显示的结果了。不幸的是,这行代码非常慢,几乎需要一整秒才能执行完。 - syntaxerror
7
因为第一个参数是间隔时间,但由于第二个参数的存在,命令只会执行一次。如果你查看命令帮助,就会发现它需要等待2秒钟才会返回结果。 - Johan Bjäreholt
问题已关闭,所以我在你的答案中添加了我的(类似的)答案 :-) 希望你不介意。像你一样,我也受到Peter Liljenberg答案的启发。 - PJ Brunet

16

编辑:我注意到在另一个用户的回答中,%idle是第12个字段而不是第11个字段。awk已更新以考虑到%idle字段是可变的。

这应该可以让您得到所需的输出:

mpstat | awk '$3 ~ /CPU/ { for(i=1;i<=NF;i++) { if ($i ~ /%idle/) field=i } } $3 ~ /all/ { print 100 - $field }'

如果您想进行简单的整数四舍五入,可以使用printf:

mpstat | awk '$3 ~ /CPU/ { for(i=1;i<=NF;i++) { if ($i ~ /%idle/) field=i } } $3 ~ /all/ { printf("%d%%",100 - $field) }'

3
mpstat 1 1 | awk '$3 ~ /CPU/ { for(i=1;i<=NF;i++) { if ($i ~ /%idle/) field=i } } $3 ~ /all/ { printf("%d",100 - $field) }'这段命令对我很有效,谢谢。注意使用mpstat 1 1以确保对CPU使用率进行一秒钟的采样。 - chrishiestand
2
如果您有jq:mpstat -o JSON -u 1 1 | jq '.sysstat.hosts[0].statistics[0]["cpu-load"][0].idle' - nyet

11

执行以下操作以查看总体CPU使用情况。这会调用python3并使用跨平台psutil模块

printf "%b" "import psutil\nprint('{}%'.format(psutil.cpu_percent(interval=2)))" | python3

interval=2 部分表示在阻塞期为2秒的情况下测量总CPU负载。

示例输出:

9.4%

这里包含的 Python 程序是:
import psutil

print('{}%'.format(psutil.cpu_percent(interval=2)))

在调用前加上time指令,可以证明此次调用需要大约2秒的时间间隔。以下是调用及结果:

$ time printf "%b" "import psutil\nprint('{}%'.format(psutil.cpu_percent(interval=2)))" | python3
9.5%

real    0m2.127s
user    0m0.119s
sys 0m0.008s

为了查看每个核心的输出,让我们使用以下Python程序。首先,我获得一个“每个CPU”信息的Python列表(数组),然后我对该列表中的所有内容进行平均处理,以获取“总% CPU”类型的值。然后,我打印总体和各个核心的百分比。
Python程序:
import psutil

cpu_percent_cores = psutil.cpu_percent(interval=2, percpu=True)
avg = sum(cpu_percent_cores)/len(cpu_percent_cores)
cpu_percent_total_str = ('%.2f' % avg) + '%'
cpu_percent_cores_str = [('%.2f' % x) + '%' for x in cpu_percent_cores]
print('Total: {}'.format(cpu_percent_total_str))
print('Individual CPUs: {}'.format('  '.join(cpu_percent_cores_str)))

如果您喜欢,可以将此内容包装成一个非常丑陋的1行bash脚本。在Python程序中,我必须确保仅使用单引号(''),而不是双引号(""),才能使这个包装工作成为一个bash 1-liner:

printf "%b" \
"\
import psutil\n\
cpu_percent_cores = psutil.cpu_percent(interval=2, percpu=True)\n\
avg = sum(cpu_percent_cores)/len(cpu_percent_cores)\n\
cpu_percent_total_str = ('%.2f' % avg) + '%'\n\
cpu_percent_cores_str = [('%.2f' % x) + '%' for x in cpu_percent_cores]\n\
print('Total: {}'.format(cpu_percent_total_str))\n\
print('Individual CPUs: {}'.format('  '.join(cpu_percent_cores_str)))\n\
" | python3

输出示例:请注意我有8个核心,所以在“单独的CPU:”后面有8个数字:

Total: 10.15%
Individual CPUs: 11.00%  8.50%  11.90%  8.50%  9.90%  7.60%  11.50%  12.30%

要了解有关Python调用psutil.cpu_percent(interval=2)的更多信息,请参见此处的官方psutil.cpu_percent(interval=None, percpu=False)文档。该函数返回一个浮点数,表示当前系统范围内的CPU利用率百分比。当interval > 0.0时,在时间间隔(阻塞)之前和之后比较系统CPU时间经过的时间。当interval为0.0或None时,自上次调用或模块导入以来比较系统CPU时间经过的时间,并立即返回。这意味着第一次调用会返回一个无意义的0.0值,您应该忽略它。在这种情况下,建议每次调用此函数之间至少延迟0.1秒以获取精确度。当percpu为True时,返回表示每个CPU利用率百分比的浮点数列表。列表的第一个元素是指第一个CPU,第二个元素是指第二个CPU等等。列表的顺序在调用中保持一致。
注意:第一次使用interval = 0.0或None调用此函数时,它将返回一个无意义的0.0值,您应该忽略它。
进一步了解:
我在我的cpu_logger.py脚本中使用上述代码,在eRCaGuy_dotfiles存储库中。参考文献:1. Stack Overflow: How to get current CPU and RAM usage in Python? 2. Stack Overflow: Executing multi-line statements in the one-line command-line? 3. How to display a float with two decimal places? 4. Finding the average of a list
  1. https://unix.stackexchange.com/questions/295599/how-to-show-processes-that-use-more-than-30-cpu/295608#295608
  2. https://askubuntu.com/questions/22021/how-to-log-cpu-load

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接