我想从python脚本运行Python脚本(或任何可执行文件,以这种方式),并实时获取输出 。我遵循了许多教程,而我当前的代码如下:
import subprocess
with open("test2", "w") as f:
f.write("""import time
print('start')
time.sleep(5)
print('done')""")
process = subprocess.Popen(['python3', "test2"], stdout=subprocess.PIPE)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
rc = process.poll()
为清楚起见,第一位只是创建将要运行的文件。
此代码有两个问题:
它不实时提供输出。它等待直到该过程完成。
进程完成后,它不会终止循环。
非常欢迎任何帮助。
编辑:感谢@JohnAnderson解决了第一个问题:将if output == '' and process.poll() is not None:
替换为if output == b'' and process.poll() is not None:
答案 0 :(得分:1)
昨晚我开始使用管道进行此操作:
import os
import subprocess
with open("test2", "w") as f:
f.write("""import time
print('start')
time.sleep(2)
print('done')""")
(readend, writeend) = os.pipe()
p = subprocess.Popen(['python3', '-u', 'test2'], stdout=writeend, bufsize=0)
still_open = True
output = ""
output_buf = os.read(readend, 1).decode()
while output_buf:
print(output_buf, end="")
output += output_buf
if still_open and p.poll() is not None:
os.close(writeend)
still_open = False
output_buf = os.read(readend, 1).decode()
强制从图片中缓冲并一次读取一个字符(以确保我们不会阻止已填充缓冲区的进程的写入),在进程结束时关闭写入端,以确保读取正确捕获了EOF。看过subprocess
似乎有点过头了。有了PIPE
,您可以免费获得其中的大部分,而我得到的结果似乎还不错(调用读取了多次以保持空管状态),并假设此过程完成了,您没有担心轮询它和/或确保管道的写端已关闭以正确检测EOF并退出循环:
p = subprocess.Popen(['python3', '-u', 'test2'],
stdout=subprocess.PIPE, bufsize=1,
universal_newlines=True)
output = ""
output_buf = p.stdout.readline()
while output_buf:
print(output_buf, end="")
output += output_buf
output_buf = p.stdout.readline()
“实时”要少一些,因为它基本上是行缓冲的。
注意:我已经向您的Python调用中添加了-u
,因为您还需要确保被调用进程的缓冲不会受到阻碍。