我的测试脚本如下所示:
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_$cpu
和prev_idle_$cpu
,但我不知道如何设置条件。我需要sed -ne 's/^cpu\(.*\) .*/\1/p' /proc/stat
的反面,所以我可以遍历它的输出并进行初始化。
答案 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
。