2

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

4
  • Whats the output of mpstat | grep "all" | cut -c 92- ?
    – heemayl
    Sep 3, 2015 at 0:08
  • You can use htop $ sudo apt-get install htop && htop
    – Pavak Paul
    Sep 3, 2015 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, 2015 at 11:53
  • Got everything working (sorry that took so long). I tried htop, but I can seem to use grep because it's interactive and refreshes itself. I'm currently using "mpstat 1 1 | grep "Average" | cut -c 92-", but it takes a full second to get an output, and the way I'm using it, it locks up my entire system for the duration of any issued command. As that command takes 1 second to get an output, it freezes for that time. If anyone happens to know a command that can get the usage over the period of maybe 1/10 of a second, or even better instantaneously, I'm open to suggestions.
    – user401317
    Sep 16, 2015 at 21:16

3 Answers 3

2

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"
22.75

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

$ echo "100 - 45.34" | bc
54.66

$ bc <<<"100 - 45.34"
54.66

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[^ ]+$'
4
  • 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, 2015 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, 2015 at 0:37
  • @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, 2015 at 1:00
  • @Ben I have installed sysstat, well..you can do mpstat | grep -Po 'all.* \K[^ ]+$'
    – heemayl
    Sep 3, 2015 at 1:15
0

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/

0

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
avg_cpu_use=$(uptime)
# 2. split response
IFS=',' read -ra avg_cpu_use_arr <<< "$avg_cpu_use"
# 3. find cpu usage
avg_cpu_use=""
for i in "${avg_cpu_use_arr[@]}"; do :
    if [[ $i == *"load average"* ]]; then
        avg_cpu_use=$i
        break       
    fi
done
# 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
else
    avg_cpu_use="CPU: ${avg_cpu_use} perc used"
fi

You must log in to answer this question.