Shell How to get cpu usage per core for my script

Hey folks,

i build my own monitoring script and found only one fastest solution to get cpu usage per core, with:
# vmstat -P
procs  memory       page                    disks     faults        cpu0     cpu1     cpu2     cpu3     cpu4     cpu5     cpu6     cpu7  
r b w  avm   fre   flt  re  pi  po    fr   sr ad0 ad1   in    sy    cs us sy id us sy id us sy id us sy id us sy id us sy id us sy id us sy id
0 0 0 742M   30G    29   0   0   0    37    1   0   0    5   383   111  0  0 100 0  0 100 0  0 100 0  0 100 0  0 100 0  0 100 0  0 100 0  0 100
It looks not perfect for me to extract usage per each core. May be anyone can recommend the best and easiest solution to get only cpu info for this command, without cut awk sed etc.

Many thanks in ahead.
It doesn't look like it. You can reduce the information a little, by issuing vmstat -Pn0, but you're still going to have to chop it up with something. As the output is fixed, awk makes a quick hack.

$ vmstat -Pn0
procs memory page faults cpu0 cpu1
r b w avm fre flt re pi po fr sr in sy cs us sy id us sy id
0 0 0 10290M 50M 742 0 0 0 416 192 324 36000 1085 4 2 94 4 2 94

so ...

vmstat -Pn0 | awk '{getline;getline;print $15,$16,$17" -- "$18,$19,$20}'
4 2 94 -- 4 2 94

and if you want the number of cpu's to be variable:

$ vmstat -Pn0 | awk 'BEGIN{cpu_count=2}{getline;getline;for(c=cpu_count-1;c>=0;c--){print "CPU: "c" "$(NF-c*3-2)","$(NF-c*3-1)","$(NF-c*3);}}'
CPU: 1 4,2,94
CPU: 0 4,2,94

thanks leebrown66,

well it's a nice try, but we have some problems. The first line of "vmstat -P" show always the same, so a wrong output. We need the second output line, by doing this with command "vmstat -P -c2"
Furthermore we have to know how many cores this CPU have. This can be done with the following command: $(sysctl hw.ncpu | awk '{print $2}')
So my solutions looks not great but its also long ugly and super slow :rolleyes:
# time vmstat -P -c2 | tail -n1 | rev | xargs -n3 | rev | head -$(sysctl hw.ncpu | awk '{print $2}') | awk '{print $3}'
        1.04 real         0.00 user         0.00 sys
or with top -P
# time top -P -d2 c | grep 'CPU [[:digit:]]' | cut -d',' -f5 | sed 's/ //g' | cut -d'%' -f1 | cut -d'.' -f1
        2.12 real         0.00 user         0.00 sys

As u can see top is a little bit slower as vmstat. However, both solutions looks not perfect for me.

I look forward to better suggestions. :)
The first line of "vmstat -P" show always the same, so a wrong output
I don't understand. It does exactly what the man page vmstat(8) says
The first display is for the
time since a reboot and each subsequent report is for the time
period since the last display

So by adding -c2, you are asking for 2 lines to be output, with a 1 second sample period (is this sample period what you perceive as "super slow").

This has the sample period reduced to 1/10 second and the cpu count plucked from sysctl.
$ CPU_COUNT=`sysctl -n hw.ncpu`;vmstat -Pn0 -c2 -w0.1 | awk 'BEGIN{getline;getline;getline}{for(c='$CPU_COUNT'-1;c>=0;c--){print "CPU: "c" "$(NF-c*3-2)","$(NF-c*3-1)","$(NF-c*3);}}'
CPU: 1 14,0,86
CPU: 0 0,7,93

Statistically speaking, I'm not sure this will mean what you expect it to though.
OK I mean the first display is not relevant, thank you. But, do you see the output of your command? Im my case it show me something like this:
# CPU_COUNT=`sysctl -n hw.ncpu`;vmstat -Pn0 -c2 -w0.1 | awk 'BEGIN{getline;getline;getline}{for(c='$CPU_COUNT'-1;c>=0;c--){print "CPU: "c" "$(NF-c*3-2)","$(NF-c*3-1)","$(NF-c*3);}}'
CPU: 7 0,0,100
CPU: 6 0,0,100
CPU: 5 0,0,100
CPU: 4 7,93,0
CPU: 3 0,0,0
CPU: 2 0,0,100
CPU: 1 0,0,0
CPU: 0 0,0,100
Take a look to the cpu 1 and 3. It show us that the core is not idle, it does not used by user or system. That cannot be. So we need a little bit more time to detect average of each core.
Which is why the default is probably 1 second.
I suppose vmstat isn't really designed to be used this way. It would produce more meaningful information in constant output mode.
Apologies for the late post. kern.cp_times (sic) was a new one for me, assuming worthwhile to mention.

 $ sysctl kern.cp_time
12653 0 4350 3054 929318
 $ sysctl kern.cp_times
2712 0 1100 555 234956
3438 0 1036 148 234638
3553 0 1175 223 234309
3063 0 1079 2152 232966

Some newlines added to make it easier to look at.

If you run in a loop, maybe you can calculate the percentages yourself.