1

I'm trying to write a script to help my company with some of our investigations. I can't install any extra packages on the systems and I need to be able to get the current processor load total in percentage.

So far I can't find any native python module that allows this so I am trying to use a bash command: ps aux|awk 'NR > 0{s +=$3};END{print "CPU %",s}'

I have been trying it in os.system and os.popen and I can't seem to get it to execute properly.

import os, multiprocessing
p = os.system("ps aux|awk 'NR > 0 { s +=$3 }; END {print "cpu %",s}'")
print "Cores:", multiprocessing.cpu_count(), '\nCPU Load:', p

I could use a hint or two. I know you're supposed to separate the command and args with a ',' in os.system but I have tried and I can't seem to get it to work. Does anyone know of a better way to execute a long one-liner in Python?

I am new to python and appreciate any answers given. Thank you.

2 Answers2

1

Try

import os, multiprocessing
p = os.popen("ps aux|awk 'NR > 0 { s +=$3 }; END {print s}'").read().rstrip("\n")
print "Cores:", multiprocessing.cpu_count(), '\nCPU Load:', p, "%"

gives

Cores: 4
CPU Load: 5.1 %
uselpa
  • 18,732
  • 2
  • 34
  • 52
1

You were almost there: just needed to "escape" the quotes ( i.e. use print \" instead of print " , etc) to get the first line right:

import os, multiprocessing
p = os.system("ps aux|awk 'NR > 0 { s +=$3 }; END {print \"cpu %\",s}'")

And you should recognize that the os.system command returns the "return code" - the answer to the question "did this process end normally?". Thus the value of p is 0 "no error", not the cpu load which was in the variable s. Not sure why you need it twice since you already printed it out. Change the last line to

print "Cores:", multiprocessing.cpu_count(), '\n'

And the output becomes something like:

cpu% 65.7
Cores: 2 

If you actually want to get the output of your system command straight into a variable, you could look at the answer given to this earlier question - it shows you how to use subprocess.Popen() and proc.communicate() to do exactly that. But just getting the command line right (with the escaped quote) is the most critical fix.

update two complete and working examples of the Popen() and system() methods follow:

import os, multiprocessing, subprocess
# two ways to get CPU load and number of CPUs

# command line string to obtain CPU load:
commandString = "ps aux|awk 'NR > 0 { s+=$3 }; END {print \"CPU%\", s}'"
print "Command string used to obtain CPU load:"
print commandString, "\n"

# obtain number of CPUs from the multiprocessing function:
numCPUs = multiprocessing.cpu_count()

# method 1: issue an os.system command, have the result echoed directly to output:
print "Method 1:"
p = os.system(commandString)
print "Cores:", numCPUs, "\n"

# method 2: return the value to a python variable:
cpu = subprocess.Popen(commandString, stdout=subprocess.PIPE, shell=True)
(out, err) = cpu.communicate()
print "Method 2:"
print "Load: ", out,
print "Cores:", multiprocessing.cpu_count(), '\n'

Output of the above:

Command string used to obtain CPU load:
ps aux|awk 'NR > 0 { s+=$3 }; END {print "CPU%", s}' 

Method 1:
CPU% 18.5
Cores: 2 

Method 2:
Load:  CPU% 24.1
Cores: 2 
Community
  • 1
  • 1
Floris
  • 45,857
  • 6
  • 70
  • 122
  • Thanks for the answer. Still not working, though. I looked at that post and modified my script: `import subprocess, multiprocessing cpu = subprocess.Popen(["ps aux|awk 'NR > 0{s +=$3;END{print \"CPU %\",s'"], stdout=subprocess.PIPE, shell=True) (out, err) = cpu.communicate() print "Cores:" multiprocessing.cpu.count(), '\n' print "Load", out` I am still getting errors. It is coming back with "unexpected newline or end of string" at the second 's'. Thanks for the escaped quote. Didn't think about that. :) – user1675042 Jun 08 '13 at 19:21
  • There are several typos in your command: you are opening `{` and not closing them... I have updated my answer "for completeness" - note that by putting the command string in its own variable you see the difference between the two calls more clearly. – Floris Jun 08 '13 at 20:43