2

I wrote a script for my dwm statusbar. One part of it is finding the current cpu usage for every single core on my system. I figured out a way myself but I would need some help fixing a bug in this. Here is the command: top -bn 2 -d 0.5 | grep -F '%Cpu' | tail -n 4 | awk '{print $3}'. This assumes that your top shows every core per default. You can achieve this by issuing top then pressing 1 and then pressing W to save the current configuration to a .toprc file in your home folder. Everytime you open top now it will display all of your cores. My aforementioned command has the drawback that when assigned to a variable like this:

CPU=$(top -bn 2 -d 0.5 | grep -F '%Cpu' | tail -n 4 | awk '{print $3}')

and then using $CPU with xsetroot like this: xsetroot -name "$CPU" I will get the output I want in my statusbar but between every cpu percentage there will be two symbols on top of each other separating them v and t. How do I get rid of them? Has this something to do that I might be using an array instead of a string here?

You can see the problem on the left side of the picture.

Command:

top -bn 2 -d 0.5 | grep -F '%Cpu' | tail -n 4 | awk '{print $3}'

sample output:

14.3
12.0
8.0
10.0

Note for anyone using this script: When the cpu usage for a core reaches 100% the array that the command outputs will move the column with the current load from column 3 to column 2. Hence, with awk '{print $3}' you will then see us, as output for column 3. If you're fine with that leave it. If not you could have awk print column 2 as well. It will just be :. A solution that avoids all those pitfalls is:

top -bn 2 | grep -F '%Cpu' | tail -n 4 | gawk '{print $2 $3}' | tr -s '\n\:\,[:alpha:]' ' '
lord.garbage
  • 2,323
  • 5
  • 27
  • 41
  • Fell free to edit the title if you have a better one. – lord.garbage Aug 31 '14 at 13:10
  • Which OS do you use and post output of `top -bn 2 -d 0.5`. – Cyrus Aug 31 '14 at 13:15
  • `Archlinux` with kernel version `3.16.1-1-ARCH`; `x86-64`. You really don't wanna see the ouput of `top -bn 2 -d 0.5` that will be an aweful long list of running processes... – lord.garbage Aug 31 '14 at 13:20
  • Off-topic: you may prefer to read `/proc/stat` to get the same information more cheaply. See `proc(5)`. – aecolley Aug 31 '14 at 16:32
  • Thought about this too... Do you have a solution at hand how to do this? – lord.garbage Aug 31 '14 at 16:39
  • it might be useful (and probably faster) to calculate it: see http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat – wmmso Sep 01 '14 at 17:10
  • I'm currently working on something like that. Will post soon. – lord.garbage Sep 01 '14 at 17:28
  • @aecolley and @wmmso I tried using `/proc/stat`. You can judge how succesful this has been for yourself here: http://unix.stackexchange.com/questions/152988/how-to-get-cpu-usage-for-every-core-with-a-bash-script/153039#153039. Corrections more than welcome if I should have made a mistake regarding the calculations. – lord.garbage Sep 02 '14 at 04:32

1 Answers1

3

The "stuff" between the values seems a visual representation of the newline character to me ( octal character code 12), which you would get when using:

echo -e 'a\012b'

What you could try is pipe the output through tr '\n' ' ' as with:

echo -e 'a\012b' | tr '\n' ' '
lord.garbage
  • 2,323
  • 5
  • 27
  • 41
Anthon
  • 78,313
  • 42
  • 165
  • 222
  • Cheers, you were close! It seems it's not a visual representation of the vertical tab bar but rather a newline. As I suspected the problem might be that I assign a `4x1` array to a bash variable and pass this to `xsetroot`. By removing the newline I get either a string or a `1x4` array. I'm not sure. So I need to pipe the output through `tr '\n' ' '`. Could you update your answer? – lord.garbage Aug 31 '14 at 15:07
  • I believe the rogue character is a newline (i.e. linefeed), even though it is displayed as VT. Therefore the correct filter is `tr '\012' ' '`. – aecolley Aug 31 '14 at 16:21