gpt4 book ai didi

python - 使用 `subprocess.Popen` 实时在 Python 中运行 Python 脚本

转载 作者:太空宇宙 更新时间:2023-11-04 04:18:48 28 4
gpt4 key购买 nike

我想从 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 '' 和 process.poll() 不是无:

最佳答案

昨晚我开始使用管道来完成此操作:

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 你可以免费获得其中的大部分,我以这个似乎工作正常结束(调用 read 多次必要以保持清空管道)就这样并假设过程完成,你不必担心轮询它和/或确保管道的写入端已关闭以正确检测 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()

这不太“实时”,因为它基本上是行缓冲的。

注意:我已将 -u 添加到您的 Python 调用中,因为您还需要确保被调用进程的缓冲不会妨碍。

关于python - 使用 `subprocess.Popen` 实时在 Python 中运行 Python 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54892371/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com