我正在后台运行一个长时间的进程(实际上是另一个 Python 脚本)。 我需要知道它何时完成。 我发现 Popen.poll()
始终返回 0,用于后台进程。是否有其他方法可以做到这一点?
p = subprocess.Popen("sleep 30 &", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)
上面的代码从不打印出None
。
我正在后台运行一个长时间的进程(实际上是另一个 Python 脚本)。 我需要知道它何时完成。 我发现 Popen.poll()
始终返回 0,用于后台进程。是否有其他方法可以做到这一点?
p = subprocess.Popen("sleep 30 &", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)
上面的代码从不打印出None
。
你不需要使用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)
我认为您想要使用popen.wait()
或popen.communicate()
命令。使用Communicate将获取您放入PIPE
中的stdout
和stderr
数据。如果另一个项目是Python脚本,我建议避免运行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)
这些代码会阻塞主线程并等待其他进程完成,这可能不太好。如果您想要忙等待,那么可以将原始代码放入循环中。 (顺便说一下,您的原始代码对我来说打印了“None”)
以下是使用循环解决方案的示例:
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)
你不应该在脚本末尾加上&符号来运行,因为Shell会复制你的进程并返回0退出代码。
&
),这使得子进程开始一个子子进程,然后退出自身 - 这就是为什么你得到0
(进程完成)而不是None
(仍在运行)。 - xjcl