Bash 使用ps、awk和sysctl计算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。答案很快就显

在我的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
。答案很快就显而易见了:它利用了一个内核,而这台机器有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
    %cpu
    是根据任务起点为每个任务计算的。-有关详细信息,请参阅man ps“%cpu”
  • 从/proc读取系统“官方”平均负载(cat/proc/loadavg)
  • 使用提取数据的实用程序:正常运行时间、top-n1等
我建议使用cat/proc/loadavg

(2) CPU计数的来源

已在回答/评论中解决并讨论

(3) 分部

可以使用“awk”或“bc”或bash(使用scaled)来执行浮点运算。假设负载,ncpu计算之前:

  • 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
}