【发布时间】:2019-12-19 13:40:21
【问题描述】:
嗨,我花了几天时间在 stackoverflow 上阅读答案,为什么我得到下面列出的输出,而不是永远看到 hello.py 中的循环计数。对我来说仍然不清楚,没有任何效果。如何在 POpen 子进程中启动一些脚本并连续获取它们的输出。不是在它们完成后,因为它们将永远运行。如果这被认为已经得到解答,如果有人可以链接到 Python3 的功能,我会很高兴。
我运行这个 .py 代码是希望看到 hello.py 执行:
import subprocess
import sys
command = [sys.executable, 'hello.py']
process_handle = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
while process_handle.poll() is None:
for line in iter(process_handle.stdout.readline, ""):
output = line.decode('utf-8')
if output != '':
print('Last number is: ' + output)
这是我得到的。没有运行 hello.py:
Linux 上的 Python 3.7.3(默认,2019 年 4 月 3 日,05:39:12)[GCC 8.3.0] 输入“help”、“copyright”、“credits”或“license”了解更多信息。
hello.py 包含:
i = 0
while True:
print(i)
i=i+1
sleep(1)
我尝试了来自live output from subprocess command 的第二个重复建议的第一个变体
它不编译/执行:
import subprocess
import sys
with open('test.log', 'w') as f: # replace 'w' with 'wb' for Python 3
process = subprocess.Popen(your_command, stdout=subprocess.PIPE)
for c in iter(lambda: process.stdout.read(1), ''): # replace '' with b'' for Python 3
sys.stdout.write(c)
f.write(c)
结果:
Traceback(最近一次调用最后一次):文件“hello.py”,第 11 行,在 Traceback(最近一次调用最后一次):文件“hello5.py”,行 7、在 sys.stdout.flush() NameError: name 'sys' is not defined sys.stdout.write(c) TypeError: write() argument must be str, not bytes
现在我尝试了上面的第二个变体,修改如下:
import subprocess
import sys
command = [sys.executable, 'hello.py']
process = subprocess.Popen(command, stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, b''): # replace '' with b'' for Python 3
sys.stdout.write(line)
结果:
Traceback(最近一次调用最后一次):文件“hello.py”,第 11 行,在 Traceback(最近一次调用最后一次):文件“hello5.py”,行 8、在 sys.stdout.flush() NameError: name 'sys' is not defined sys.stdout.write(line) TypeError: write() argument must be str, not bytes
根据 ShadowRanger 的建议,我为二进制添加了 b'',但是 sys 已经导入:
import subprocess
import sys
command = [sys.executable, 'hello.py']
process = subprocess.Popen(command, stdout=subprocess.PIPE)
for c in iter(lambda: process.stdout.read(1), b''): # replace '' with b'' for Python 3
sys.stdout.write(c)
结果,尽管添加了import sys,sys没有定义?另外现在它抱怨二进制并想要字符串。
Traceback(最近一次调用最后一次):文件“hello.py”,第 11 行,在 sys.stdout.flush() NameError: name 'sys' is not defined 回溯(最近一次调用最后):文件“hello5.py”,第 8 行,在 sys.stdout.write(c) TypeError: write() argument must be str, not bytes
好的,我使用 ShadowRanger 的信息并将二进制输出再次转换为文本。 hello.py 现在正在打印文本。
sys.stdout.write(c.decode('ASCII'))
但它一下子就来了,这不是我需要的。 hello.py 中的每一行打印都必须实时显示,而不仅仅是脚本完成时。
【问题讨论】:
-
@Chris 感谢您的建议。该线程中接受的答案是将 sys.stdout.flush() 添加到打印中。我将它添加到我所有的 print() 中,但不幸的是仍然没有结果。
-
仅供参考,所有双参数
iter调用的第二个参数都是错误的;你传递了"",空的str,但是你的Popen调用都是默认的二进制模式,所以你应该使用b""。您的最终回溯只是因为您在hello5.py脚本中使用了sys.stdout而没有使用import sys,和/或您没有使用sys.stdout.buffer.write(c)(因为再次,您有bytes,并且您试图写信给基于文本的sys.stdout)。 -
@Rimfire:它在您的一个脚本的导入中,但不是由
Popen运行的那个。write的错误是因为read/readline仍然返回bytes。你需要先了解bytes和str在 Python 3 中是如何工作的;如果您不理解这一点,而只是使用subprocess复制和粘贴为 Python 2 编写的代码,那么您将在错误之上遇到错误。有多种可能的修复方法,但如果您没有了解问题的背景知识,我不会通过零碎地指出问题来提供帮助。
标签: python python-3.x