tags:

views:

646

answers:

5

Hey all, I'm trying to make a system call in Python and store the output to a string that I can manipulate in the Python program.

#!/usr/bin/python

import subprocess

p2 = subprocess.Popen("ntpq -p")

I've tried a few things including some of the suggestions here:

http://stackoverflow.com/questions/1996518/retrieving-the-output-of-subprocess-call

but without any luck.

Many thanks!

A: 

The os.cwd() function does what you are trying to accomplish with this call, and in a more portable manner to boot.

Anyway, like the answer you linked to suggests, pass the PIPE argument to the Popen constructor. Then you can read from p.stdout as from any other file-like object. Something like this (untested):

p2 = subprocess.Popen("ntpq -p", stdout = subprocess.PIPE)
output = p2.stdout.read()
Thomas
I just used pwd as an example. I actually want to store the output of ntpq -p.
mark
From http://docs.python.org/library/subprocess.html: "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."
Mark Byers
@Thomas, your code does not work because `Popen` doesn't invoke the shell. It will look for a binary named `ntpq -p` which does not exist.
Mike Graham
@Mark Bryers, @Mike Graham: good point. Upvote Mike Graham instead!
Thomas
+3  A: 

This worked for me for redirecting stdout (stderr can be handled similarly):

from subprocess import Popen, PIPE
pipe = Popen(path, stdout=PIPE)
text = pipe.communicate()[0]

If it doesn't work for you, please specify exactly the problem you're having.

Eli Bendersky
+2  A: 

Assuming that pwd is just an example, this is how you can do it:

import subprocess

p = subprocess.Popen("pwd", stdout=subprocess.PIPE)
result = p.communicate()[0]
print result

See the subprocess documentation for another example and more information.

Mark Byers
+8  A: 

Use the communicate method.

import subprocess
p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE)
out, err = p.communicate()

out is what you want.

Note how I passed in the command. The "ntpq -p" example brings up another matter. Since Popen does not involke the shell, you would use a list of the command and options—["ntpq", "-p"].

Mike Graham
Need `()` after communicate, else it will die trying to assign one thing (the method itself) to two.
Mike DeSimone
@Mike DeSimone, Oops! Thanks for pointing out my typo.
Mike Graham
Thanks very much. Apologies for posting a bad example at first all!
mark
In this case, does python wait for this system call to finish? Or is it necessary to explicitly call the wait/waitpid function?
NoneType
@NoneType, `Popen.communicate` does not return until the process has terminated.
Mike Graham
A: 
 import os   
 list = os.popen('pwd').read()

In this case you will only have one element in the list.

windfinder
`os.popen` is deprecated in favour of the `subprocess` module.
Mike Graham