python - 从子进程获取无缓冲的输出无法正常工作 Python
问题描述
我有一个可执行文件,如果我使用标志运行它,它会启动一个始终生成消息的工具。当我尝试使用子进程运行它时,我得到了 cmd 的输出,这很好。问题是我想接收这些消息并对它们做一些事情,但由于某种原因,unbuffring 方法不起作用,我没有收到任何消息。
以下是我尝试过的代码:
p = subprocess.Popen(
["my_tool.exe","runMode","y","port","1234"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT, bufsize=1)
要生成输出,请尝试以下操作:
for line in p.stdout:
print("CUR", line)
和:
while p.poll() is None:
line = p.stdout.read(2)
print("Print:" + line)
和:
for line in iter(p.stdout.readline, b''):
print(line)
p.stdout.close()
知道为什么 stdout 行上的代码总是阻塞吗?
更新:
例如,如果我有以下无限程序:
inf.py
import time
i = 0
while True:
time.sleep(0.5)
print(i)
i += 1
以及运行它的以下代码:
p = subprocess.Popen(r"C:\Python35\python.exe inf.py",
stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)
并生成我使用上述方法之一的输出,如果我使用 CTRL+C 停止它,它总是卡在这一行:
File "C:\Python35\lib\encodings\cp1252.py", line 22, in decode
def decode(self, input, final=False):
解决方案
首先我设置以下环境变量:
PYTHONUNBUFFERED=1
然后我稍微改变了你的代码:
read_infinite.py
import subprocess
binary = "C:\\Python35\\python.exe"
script = "C:\\temp\\python\\tests\\inf.py"
p = subprocess.Popen([binary, script], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)
while p.poll() is None:
#line = p.stdout.read(2)
line = p.stdout.readline()
if line:
print("Result: %r" % line)
删除bufsize=1
工作相同。
我最初得到的错误是找不到 inf.py,但这没有显示,因为 read_infinite.py 的打印将错误滚动了出来。并且在很多行“结果:”(变量“行”为空)之后,该过程停止了。
打印后删除if line:
和添加time.sleep(0.5)
(记住import time
!)显示相同的结果。
所以解决方案是:父母必须等待孩子。
推荐阅读
- php - Symfony 无法访问自定义类/方法中的 EntityManager
- react-native - _NativeStripeSdk.default.createToken 未定义
- php - 问题:部分 PHP 练习没有正确运行
- php - 带有代理的 WSS 使用端口 443 浏览器客户端连接到端口 6001 上的 websocket 服务器
- arrays - CS50 Caesar 输出为 aaaaa
- vba - 如何为 VBA 自动化创建例程
- jenkins - Jenkins + OpenLiteSpeed NodeJS 集成
- authentication - Keycloak invalid_grant 与授权授予流程
- youtube-api - YouTube 数据 API - 成员:列出代码 403
- rust - 仅使用顶点和索引时如何画线?