I have a problem where I am issuing a command using python and then taking in the values to create a list of services.
serviceList = subprocess.Popen(command, shell=True, stdout =subprocess.PIPE).stdout.read()
print serviceList
command is a working command that works perfectly when I copy and paste it into cmd, giving me a list of services and their status.
If I run this command it just returns nothing. When I print out serviceList it is blank.
I am using python 2.7
4 Answers 4
You must use communicate() method instead of stdout.read() to get the value of serviceList.
Even the Python docs recommend it.
Warning: Use
communicate()rather than.stdin.write,.stdout.reador.stderr.readto avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.
Try this:
proc = subprocess.Popen(command, shell=True, stdout =subprocess.PIPE)
serviceList = proc.communicate()[0]
print serviceList
communicate() returns a tuple (stdoutdata, stderrdata). Here, i assign the first element of the tuple to serviceList.
1 Comment
If the program simply prints out a bunch of information then exits, an easier way (also no way for it to deadlock due to full buffer) to read output would be to call:
process = subprocess.Popen(command) # only call shell=True if you *really need it
stdoutdata, stderrdata = process.communicate() # blocks until process terminates
*Calling shell=True with external input opens your code to shell injection attacks, and should be used with caution
Comments
To save the standard output, add output = serviceList.stdout.readlines() to your code.
2 Comments
serviceList = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read() are you sure that you are adding quotation marks around the command that you're trying to run? It's working fine for me in my python interpreter.There's also the subprocess function check_output() which blocks and returns the output of the process as a byte-string. If you want to avoid blocking, you could make a function that calls this and use it as that target for a new Thread() e.g.
import subprocess
import threading
def f():
print subprocess.check_output([command])
threading.Thread(target=f).start()
print serviceList.communicate()