python 为什么 subprocess.Popen(...) 不总是返回?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/694000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
why doesn't subprocess.Popen(...) always return?
提问by dF.
I hope this is a simple python question.
我希望这是一个简单的 Python 问题。
When I try the following in the python interpreter:
当我在 python 解释器中尝试以下操作时:
>>> 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.
它将运行ls -l
,但我需要点击“返回”以获得新的 >>> 提示。
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.
然后ls -l
将立即出现 >>> 提示。
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.
最后一个例子最接近我想要的。我的目标是启动一个子进程,等待它完成,然后通过引用在我的父进程中使用它的 stdout,p.stdout
同时让 stderr 只打印到其他地方。
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()
.
现在在我的实际应用程序中,最后一个版本只是挂在:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
有或没有p.wait()
.
Thanks,
谢谢,
Charlie
查理
回答by dF.
In the first variation, test()
returns immediately after starting the process, but before its output is sent to the console.
在第一个变体中,test()
在启动进程后立即返回,但在其输出发送到控制台之前。
If you look at the output you doget the prompt, immediately before the output of ls
.
如果你看一下你的输出做弹出提示,立即输出之前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.
在第二个变体中,test()
在返回之前等待进程终止。
In the third version, you're right that you may have to read from the child process's stdout
for it to continue.
在第三个版本中,您可能必须从子进程中读取stdout
才能继续。
回答by dF.
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.stdout 中明确读取,以便我的过程继续。
ie:
IE:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = p.stdout.readlines()
....
Thanks all
谢谢大家
回答by user3273866
Just use communicate() method.No need to return.
只需使用communication() 方法。无需返回。
>>> test(['ls', '-l'])
>>>
>>> def test(cmd):
... p = subprocess.Popen(cmd).communicate()
...
>>> test(['ls', '-l'])
回答by storm_m2138
Here is a command that pings Google forever, so it needs to be manually terminated to retrieve the output.
这是一个永远 ping Google 的命令,因此需要手动终止它以检索输出。
See the subprocess documentationfor instructions on converting os.popen() method calls to full subprocess.Popen classes.
有关将 os.popen() 方法调用转换为完整 subprocess.Popen 类的说明,请参阅子流程文档。
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