0

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

7
  • 1
    And what happens when you enter this in python? Commented Jul 13, 2015 at 17:32
  • oh sorry i completely forgot to put that in. it just gives me a blank space, or an empty list Commented Jul 13, 2015 at 17:34
  • 1
    Try print serviceList.communicate() Commented Jul 13, 2015 at 17:36
  • gives me the error str object has no attribute communicate, I will try this with os instead of subprocess Edit: still gives the same error Commented Jul 13, 2015 at 17:40
  • I think you need to post more context for your code. Commented Jul 13, 2015 at 17:46

4 Answers 4

2

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.read or .stderr.read to 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.

Sign up to request clarification or add additional context in comments.

1 Comment

This was the method that worked for me. I tried this beforehand but forgot a crucial thing. In my command string i should have put an 'r' in the beginning "r'C:\Python27\A..." is how my command should have started instead of "'C:\Python27\A"
1

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

docs:

*Calling shell=True with external input opens your code to shell injection attacks, and should be used with caution

Comments

0

To save the standard output, add output = serviceList.stdout.readlines() to your code.

2 Comments

gives me the error that str object has no attribute stdout
When you run the command 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.
0

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.