Tutorial :why doesn't subprocess.Popen(…) always return?


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




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.


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.


p = subprocess.Popen(cmd, stdout=subprocess.PIPE)  output = p.stdout.readlines()  ....  

Thanks all


Just use communicate() method.No need to return.

>>> test(['ls', '-l'])  >>>   >>> def test(cmd):  ...    p = subprocess.Popen(cmd).communicate()  ...   >>> test(['ls', '-l'])  


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  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »