Python:在后台进程上使用popen poll

时间:2012-08-21 15:02:32

标签: python python-3.x popen subprocess

我在后台运行一个很长的进程(实际上是另一个python脚本)。我需要知道它什么时候结束。我发现Popen.poll()总是为后台进程返回0。还有另一种方法吗?

p = subprocess.Popen("sleep 30 &", shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)

以上代码永远不会打印None

3 个答案:

答案 0 :(得分:32)

您不需要使用shell后台&语法,因为subprocess会自动在后台运行该进程

只需正常运行命令,然后等到Popen.poll返回not None

import time
import subprocess

p = subprocess.Popen("sleep 30", shell=True)
# Better: p = subprocess.Popen(["sleep", "30"])

# Wait until process terminates
while p.poll() is None:
    time.sleep(0.5)

# It's done
print "Process ended, ret code:", p.returncode

答案 1 :(得分:10)

您不应该在最后使用&符号运行脚本。因为shell会分叉你的进程并返回0退出代码。

答案 2 :(得分:9)

我认为您需要popen.wait()popen.communicate()命令。 Communicate将获取您放入stdout的{​​{1}}和stderr数据。如果另一个项目是Python脚本,我会通过执行以下操作来避免运行PIPE调用:

shell=True

当然这些包含主线程并等待其他进程完成,这可能是坏事。如果您想忙等待,那么您可以简单地将原始代码包装在一个循环中。 (您的原始代码确实为我打印了“无”,顺便说一句)

循环解决方案中的包装示例:

p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
print(stdout)
print(stderr)