22

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

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

上面的代码从不打印None

4

3 回答 3

43

您不需要使用 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)
于 2012-08-21T15:49:03.373 回答
15

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

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

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

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

p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while p.poll() == None:
    # We can do other things here while we wait
    time.sleep(.5)
    p.poll()
(results, errors) = p.communicate()
if errors == '':
    return results
else:
    raise My_Exception(errors)
于 2012-08-21T15:26:29.020 回答
10

你不应该在最后运行你的脚本。因为 shell fork 你的进程并返回 0 退出代码。

于 2012-08-21T15:08:35.847 回答