Reputation:
I hope this is a simple python question.
When I try the following in the python interpreter:
>>> import process
>>> def test(cmd):
... p = subprocess.Popen(cmd)
...
>>> test(['ls', '-l'])
It will run the ls -l
, but I need to hit "return" to get a new >>> prompt.
However, when I try the following:
>>> import process
>>> def test(cmd):
... p = subprocess.Popen(cmd)
... p.wait()
...
>>> test(['ls', '-l'])
Then the ls -l
will be run with a >>> prompt immediately present.
One other variation:
>>> import process
>>> def test(cmd):
... p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
...
>>> test(['ls', '-l'])
This will give me an immediate new prompt.
The last example is closest to what I want. My goal is to launch a child process, wait for it to finish and then use its stdout in my parent process by referring to p.stdout
while letting stderr just print to wherever it would otherwise.
Right now in my actual application, the last version just hangs at the:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
with or without a p.wait()
.
Thanks,
Charlie
Upvotes: 8
Views: 13872
Reputation: 2509
Here is a command that pings Google forever, so it needs to be manually terminated to retrieve the output.
See the subprocess documentation for instructions on converting os.popen() method calls to full subprocess.Popen classes.
host = "www.google.com"
command = "ping %s -t"%host
#p = os.popen(command) -- using Popen instead of os.popen() to allow calling terminate()
p = Popen(command, stdout=subprocess.PIPE)
time.sleep(5)
print "term"
p.terminate()
pingResultSoFar = p.communicate()[0] # get what has been printed to standard out so far
print pingResultSoFar
Upvotes: 1
Reputation: 604
Just use communicate() method.No need to return.
>>> test(['ls', '-l'])
>>>
>>> def test(cmd):
... p = subprocess.Popen(cmd).communicate()
...
>>> test(['ls', '-l'])
Upvotes: 0
Reputation:
I may have answered my own question. I believe that in the final case, I need to explicitly read from p.stdout in order for my process to continue.
ie:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = p.stdout.readlines()
....
Thanks all
Upvotes: 7
Reputation: 75785
In the first variation, test()
returns immediately after starting the process, but before its output is sent to the console.
If you look at the output you do get the prompt, immediately before the output of ls
.
>>> test(['ls', '-l'])
>>> total 0 <----- test() returns, new propmpt
--rw-r--r-- 1 foo bar 7 Mar 24 17:38
etc etc
In the second variation, test()
is waiting for the process to terminate before it returns.
In the third version, you're right that you may have to read from the child process's stdout
for it to continue.
Upvotes: 8