I'm trying to get the CPU's total load with this:

IDLE=$(mpstat | grep "all" | cut -c 92-)

CPULD=$(expr 100 - $IDLE)

echo $CPULD

but it always returns:

expr: non-integer argument on the second line. 

I've looked around and everyone says that integers will be automatically recognized in strings, but it doesn't seem to be working.

EDIT: For those of you who wish to see my full and now-working script, it is here: http://pastebin.com/cFQzz4Up

  • Whats the output of mpstat | grep "all" | cut -c 92- ? – heemayl Sep 3 '15 at 0:08
  • "77.25" (a string) which indicates the percentage of CPU that is currently idle. – Ben Sep 3 '15 at 0:17
  • You can use htop $ sudo apt-get install htop && htop – Pavak Paul Sep 3 '15 at 12:30
  • Are you sure about this? I'm not familiar with mstat but my tests and its manpage seem to suggest that it gives the average over the entire time the machine has been on and not the current CPU use. – terdon Sep 6 '15 at 11:53
  • I didn't know about that. I would investigate it more, but I'm currently having a GREAT time trying to get my graphucs drivers to work. – Ben Sep 6 '15 at 18:04
up vote 3 down vote accepted

bash (and expr) can not do floating point arithmetics, you need to take help of bc.

For example :

$ IDLE=$(mpstat | grep "all" | cut -c 92-)

Lets say $IDLE is 77.25.

Now you need bc :

$ IDLE=77.25

$ CPULD="$(bc <<<"100 - $IDLE")"

$ echo "$CPULD"

bc operates on files, so we can pass the manipulation string via STDIN, although i prefer here strings :

$ echo "100 - 45.34" | bc

$ bc <<<"100 - 45.34"

On a different note, to get the IDLE % of CPU, instead of mpstat | grep "all" | cut -c 92- you can do :

mpstat | grep -Po 'all.* \K[^ ]+$'
  • We posted two almost identical solutions, but indeed you were faster >:), so I'll report here the only difference, i.e. that one may also use mpstat | awk '/all/ {printf "%.2f", $12}' in place of IDLE=$(mpstat | grep "all" | cut -c 92-) (which, FWIW, looks nicer (IMO) and forks 2 processes instead of 3) – kos Sep 3 '15 at 0:33
  • @kos i know nothing about mpstat, that why i asked OP about it first.. :) ..you are right about the concept though in general :) – heemayl Sep 3 '15 at 0:37
  • Yea, I know many people prefer awk, but as you may have guessed I'm new to bash and awk is a relatively complicated command compared to grep and cut, which I personally find easier to understand, as I've picked up all my knowledge so far from looking at code and alternately prodding it with a stick and smashing it with a hammer to find out what it does :) – Ben Sep 3 '15 at 0:58
  • @Ben I have not used mpstat but i can confirm you that grep alone can do this by looking at what you are doing.. – heemayl Sep 3 '15 at 1:00
  • @Ben I have installed sysstat, well..you can do mpstat | grep -Po 'all.* \K[^ ]+$' – heemayl Sep 3 '15 at 1:15

I came up with this solution and it works for me.

echo print `top -n 1 | tr -s " " | cut -d$" " -f10 | tail -n +8 | head -n -1 | paste -sd+ | bc`/ `nproc` | python

Source (write up): https://mohammadg.com/programming/how-to-get-overall-cpu-utilization-from-the-bash-command-line/

Use the command uptime. It gives system load averages for the past 1, 5, and 15 minutes (man page).

# 1. get total average CPU usage for the past minute
# 2. split response
IFS=',' read -ra avg_cpu_use_arr <<< "$avg_cpu_use"
# 3. find cpu usage
for i in "${avg_cpu_use_arr[@]}"; do :
    if [[ $i == *"load average"* ]]; then
# 4. create response
avg_cpu_use=$(echo ${avg_cpu_use:16})   # Remove "  load average: "
if [[ -z "${avg_cpu_use// }" ]]; then
    avg_cpu_use="CPU: N/A perc used"
    exit -1
    avg_cpu_use="CPU: ${avg_cpu_use} perc used"

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.