在bash中获取CPU使用率,不使用top或sysstat

时间:2014-06-28 12:41:39

标签: bash sed cpu-usage

我的测试脚本如下所示:

prev_total_cpu=0
prev_idle_cpu=0

while true
do
 tempenv=$(grep "cpu " /proc/stat)
 #get cpu times
 read cpu user nice system idle <<< "$tempenv"

 #calculate total cpu time
 let total=$[$user + $nice + $system + $idle]

 #calculate delta total and delta idle
 prev_total="prev_total_$cpu"
 prev_idle="prev_idle_$cpu"
 let delta_total=$[$total-${!prev_total}]
 let delta_idle=$[$idle-${!prev_idle}]

 #calculate cpu usage
 printf "$cpu: $[100*($delta_total-$delta_idle)/$delta_total]%% "

 #remember total and idle times
 let prev_total_$cpu="$total"
 let prev_idle_$cpu="$idle"

 echo ""
 sleep 1
done

现在,多CPU支持也是如此:

prev_total_cpu=0
prev_idle_cpu=0
prev_total_cpu0=0
prev_idle_cpu0=0
prev_total_cpu1=0
prev_idle_cpu1=0

while true
do
 #loop through cpus
 grep "cpu" /proc/stat | while IFS='\n' read tempenv
 do
  #get cpu times
  read cpu user nice system idle <<< "$tempenv"

  #calculate total cpu time
  let total=$[$user + $nice + $system + $idle]

  #calculate delta total and delta idle
  prev_total="prev_total_$cpu"
  prev_idle="prev_idle_$cpu"
  let delta_total=$[$total-${!prev_total}]
  let delta_idle=$[$idle-${!prev_idle}]

  #calculate cpu usage
  printf "$cpu: $[100*($delta_total-$delta_idle)/$delta_total]%% "

  #remember total and idle times
  let prev_total_$cpu="$total"
  let prev_idle_$cpu="$idle"
 done
 echo ""
 sleep 1
done

不起作用 - 它一遍又一遍地显示相同的数字。我做错了什么?

子问题:

我想在循环中初始化prev_total_$cpuprev_idle_$cpu,但我不知道如何设置条件。我需要sed -ne 's/^cpu\(.*\) .*/\1/p' /proc/stat的反面,所以我可以遍历它的输出并进行初始化。

1 个答案:

答案 0 :(得分:2)

当你这样做时

grep "cpu" /proc/stat | while IFS='\n' read tempenv
do
    ...
done

您的while循环在子shell环境中运行。

一种解决方案是使用流程替换:

while IFS='\n' read tempenv
do
    ...
done < <(grep "cpu" /proc/stat)

另一种方法是在Bash支持时启用lastpipe选项:

shopt -s lastpipe
... loop goes next ...

在代码中添加一些建议,在Bash中进行算术运算时,最好使用(( ))格式,例如:

(( total = user + nice + system + idle ))

使用-n而不是printf

也可能更好
echo -n "$cpu: $(( 100 * ($delta_total - $delta_idle) / $delta_total ))%% "

最后,我希望您的确意味着您使用Bash运行脚本而不是Ksh等其他shell。他们是非常不同的。 Bash是一个shell但是Shell != Bash