0

这是针对 Windows 环境的。

编译 testprocess.py(使用 pyinstaller)并将生成的 exe 放在测试文件夹中。

在同一文件夹中,运行 ptest.py。

Testprocess.py 开始并且永远不会结束,每 3 秒向标准输出写入一个数字。

ptest.py 尝试捕获此输出。

此代码模拟了我想解决的生产问题。与生产中发生的情况类似,在 testprocess 终止之前,stdout 不会发布到 ptest.py。在生产中,这个过程永远不会停止,但它会将重要内容发布到标准输出。

有没有办法做到这一点?

只要子进程终止,附加的代码就可以正常工作。

## [testprocess.py]:

import time

x = 0

while True:
    print(x)
    time.sleep(3)
    x += 1


## [ptest.py]:

import os
import sys
import subprocess

def get_script_path():
    return os.path.dirname(os.path.realpath(sys.argv[0]))

start_dir = get_script_path()

cmd = [start_dir + os.sep + 'testprocess.exe']

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', universal_newlines=True)

print('Subprocess started.')

capture = ""

s = proc.stdout.read(1)

print('Read Stdout')

while len(s) > 0:
    sys.stdout.write(s)
    sys.stdout.flush()
    capture += s
    s = proc.stdout.read(1)
    print(s)

print(capture)

sys.exit()

希望能够在子进程仍在运行时捕获它的标准输出,而不是等到它终止。

4

1 回答 1

0

这是可能的,而且比你想象的要容易。一旦子进程启动,如果有要打印的内容,您可以不断尝试读取stdout并打印它。您可能必须修改testprocess.py以刷新自身(添加flush = Trueprint语句中)。

p = subprocess.Popen(command, 
                     stdout = subprocess.PIPE, 
                     stderr = subprocess.STDOUT, 
                     encoding='utf-8', 
                     universal_newlines=True)

while True:
    line = p.stdout.readline()
    if line == "" and p.poll() is not None:
        break
    if line:
        print(line.strip(), flush = True)

编辑:如果您的命令看起来像python testprocess.py,您可以跳过将flush = True's 添加到您的打印语句中,而是-u作为命令选项传递。告诉python解释器-uunbuffered模式下运行。

但是,我看到你的命令实际上是在调用一个exe文件。您可能需要弄清楚如何告诉您的编译器如何将您的程序编译为unbuffered.

于 2019-10-15T15:12:15.183 回答