Calculating CPU Usage from /proc/stat

I recently came across a number of forum topics asking how to calculate CPU usage from /proc/stat, which raised a very slight sense of challenge within me (was just in "the mood" to do some BASH scripting)... so, here's an example showing how to calculate CPU usage with a simple BASH script.

Note, the following script has been moved to github: https://github.com/pcolby/scripts/blob/master/cpu.sh

So check there for the latest version.

#!/bin/bash

by Paul Colby (http://colby.id.au), no rights reserved ;)

PREVTOTAL=0 PREVIDLE=0

while true; do CPU=(cat /proc/stat | grep '^cpu ') # Get the total CPU statistics. unset CPU[0] # Discard the "cpu" prefix. IDLE=${CPU[4]} # Get the idle CPU time.

# Calculate the total CPU time. TOTAL=0 for VALUE in "${CPU[@]}"; do let "TOTAL=$TOTAL+$VALUE" done

# Calculate the CPU usage since we last checked. let "DIFFIDLE=$IDLE-$PREVIDLE" let "DIFFTOTAL=$TOTAL-$PREVTOTAL" let "DIFFUSAGE=(1000*($DIFFTOTAL-$DIFFIDLE)/$DIFFTOTAL+5)/10" echo -en "\rCPU: $DIFF_USAGE% \b\b"

# Remember the total and idle CPU times for the next check. PREVTOTAL="$TOTAL" PREVIDLE="$IDLE"

# Wait before checking again. sleep 1 done

The script should be pretty self-explanatory. It loops forever (just hit Ctrl-C when you want it to stop). Each time through the loop, it calculates the CPU usage by subtracting the CPU's "idle" time from the CPU's "total" time. Notice the way the percentage is calculated by multiplying by 1000, and then dividing by 10 at the end, instead of the "normal" approach of multiplying by 100. This is actually a cunning way of rounding off :) See the way I add 5 just before the divide by 10? So, for example, if the percentage was 45.6% then BASH would truncate the result to 45%. But, by multiplying by 1000 (instead of 100), and adding 5, the result is 461 (ie 456+5), which, when divided by 10 at the end, yields the correctly rounded result of 46% :) The other neat trick in the above script is the output "echo" statement:

echo -en "\rCPU: $DIFF_USAGE%  \b\b"

This causes the script to output the CPU % on just one line - ie continually overwriting the previous value. It works like this:

Well, that's it. Any questions, or suggestions, add a comment below :)

comments powered by Disqus