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

标签 python python-3.x subprocess

我想从 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() 不是 None:

最佳答案

昨晚我开始使用管道来做到这一点:

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。尽管查看了子进程,但事实证明这有点矫枉过正。使用 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()

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

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

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

相关文章:

python - 如何使用joblib并行写入文件?可加入队列问题

未捕获python3 gspread异常

python - 如何统一stdout和stderr,同时又能够区分它们?

python - 使用 Popen 运行本地二进制文件时出现“找不到文件”错误

python - 给定一个描述 object.attribute 的 Python 字符串,如何将属性的命名空间与属性分开?

python - 有没有办法根据不同列中的离散变量制作 matplotlib 散点图标记或颜色?

python - 对大 numpy 矩阵的单元格进行排序

python - 更改其他类(class)的tkinter标签?

python - Tkinter:标签和按钮框架之间的空间太大

python - 使用 subprocess.Popen 调用 python 脚本并刷新数据