Bash 使用ps、awk和sysctl计算CPU利用率
在我的tmux配置中,我喜欢在底部的状态栏中显示一些基本统计数据(CPU使用率、内存使用率等)。为了计算CPU使用率,我之前做了以下工作:Bash 使用ps、awk和sysctl计算CPU利用率,bash,shell,awk,Bash,Shell,Awk,在我的tmux配置中,我喜欢在底部的状态栏中显示一些基本统计数据(CPU使用率、内存使用率等)。为了计算CPU使用率,我之前做了以下工作: cpuusage=$(ps -Ao pcpu | awk '{sum = sum + $1}END{printf "%4.1f", sum}') 这在我的旧Ubuntu笔记本电脑上起作用,$cpuusage的值从0.0到100.0不等。但是在我的Mac电脑上,我开始获得CPU使用率值,比如113.7或239.8——远高于我预期的最大100.0。答案很快就显
cpuusage=$(ps -Ao pcpu | awk '{sum = sum + $1}END{printf "%4.1f", sum}')
这在我的旧Ubuntu笔记本电脑上起作用,$cpuusage
的值从0.0
到100.0
不等。但是在我的Mac电脑上,我开始获得CPU使用率值,比如113.7
或239.8
——远高于我预期的最大100.0
。答案很快就显而易见了:它利用了一个内核,而这台机器有12个内核
为了纠正这个问题,我想除以内核的数量。为了获得我使用的内核数,我使用了sysctl-nhw.ncpu
。在我的Mac电脑上,返回12
。然后我试着这样分开:
cpupercent=$(($cpuusage/$(sysctl -n hw.ncpu)))
只要cpuusage
是一个可被12整除的整数,它就起作用了(例如当$cpuusage
正好是60
时,它返回5
),但是当用法不能被12整除时,它只返回一个空字符串
我怀疑问题在于,$cpuusage
是一个字符串,而不是整数或浮点(在做了一些基础研究后,我确定Bash实际上不支持浮点),但我不确定应该如何解决这个问题
我是否应该启动第二个awk
进程,并像这样传递cpu使用率和cpu数量
cpupercent=$(awk '{printf "%4.1f", $1 / $2}' <<< $cpuusage $(sysctl -n hw.ncpu))
或者我应该使用其他工具来完成这项工作,比如
bc
?这个问题提出了两点:(1)负载来源(2)CPU计数来源
(1) 负载源
- 使用电流计算(ps之和)。但是请注意,这(几乎)总是会低估当前负载,因为ps
是根据任务起点为每个任务计算的。-有关详细信息,请参阅man ps“%cpu”%cpu
- 从/proc读取系统“官方”平均负载(cat/proc/loadavg)
- 使用提取数据的实用程序:正常运行时间、top-n1等
- bc:使用:
pct=$(echo“scale=1;$load/$ncpu”| bc)
- awk:使用
pct=$(awk'END{printf“%.1f\n”,(0+0+iload)/ncpu}'iload=$load ncpu=$ncpu/dev/null)
- 纯Bash:不推荐-笨拙:
V=$((负载*100/ncpu));pct=${V:0:2}.${V:-2}
其中,我更喜欢bc-更简单、易于理解和维护。这里有一个简单的
iostat-c
与awk
组合,以获得当前的CPU利用率
iostat -c|awk 'awk '/[[:digit:]]$/{print 100-$NF}''
输出介于0-100之间
样本输出
解释
iostat-c
提供有关当前CPU利用率的一些统计信息:
Linux 3.10.0-123.el7.x86_64 (psdbperf) 10/28/2019 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.68 0.00 0.13 0.32 0.00 98.87
awk
脚本:
/[[:digit:]]$/ { # if current line ends with a digit
print (100-$NF) # print 100 - %idle
}
虽然你在帖子中提供了详细信息,但如果你能在帖子中发布sysctl-n hw.ncpu
,cpuusage
等的值,那么理解你的帖子会更好,这将有助于人们进行指导,因为所有人可能都没有mac o.s(像我一样)。我稍微更新了我的问题。我已经给出了几个$cpuusage
值的示例,它从秒到秒变化,但通常是一个字符串,如83.1
。但是我现在已经包括了sysctl-n hw.ncpu的输出,它在我的机器上打印12
,我可以在*nix机器上使用cat/proc/loadavg
,但不幸的是,整个/proc
目录在Mac OS X/Darwin机器上并不存在。我也试过top-n1,但在Mac上不起作用。虽然正常运行时间
给出了三个数字:1.67 1.84 1.88
-还不知道该怎么读,但我想应该是其中一个,我只是尝试了一下,使用bc
解决方案。由于/proc
和top
在Mac上不起作用,我放弃了当前的计算负载的方法,而当我在谷歌上搜索正常运行时间时,它似乎是一件完全不同的事情(不是CPU使用)。但是,我没有试图找到一个单一的行,而是写了三行:一行用于计算$load
,一行用于计算$ncpu
,然后是您建议组合它们的bc
行。工作得很有魅力。我还通过管道将结果传输到awk
以按照我的要求进行格式化,因为.1
看起来不像0.1%
@stevendesu正常运行时间3号与/proc/loadavg相同。它们表示最近1、5和15分钟的负载感谢澄清。当我在谷歌上搜索时,我发现的那篇文章说,uptime
命令中的“负载”是指有多少进程在使用CPU(例如,如果有5个进程在使用CPU,“负载”是5),而不是实际的利用率百分比。所以我现在坚持使用我的ps
解决方案,因为这会给我一个基于百分比利用率的值。
Linux 3.10.0-123.el7.x86_64 (psdbperf) 10/28/2019 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.68 0.00 0.13 0.32 0.00 98.87
/[[:digit:]]$/ { # if current line ends with a digit
print (100-$NF) # print 100 - %idle
}