尝试读取 proc.stdout.readline 中的所有行时陷入无限循环

问题描述 投票:0回答:3

我正在尝试读取 proc.stdout.readline 中的每一行并通过网络发送这些行,例如:

data = b''
for line in iter(proc.stdout.readline, ''):
    data += line
clientsocket.send(data)

当我运行这段代码时,我似乎陷入了无限循环,无法逃脱到该行:

clientsocket.send(data)

有没有更高效的读取数据的方法?我也尝试过使用 while 循环并打破“if not line”:

data = b''
while True:
    line += proc.stdout.readline()
    data += line
    if not line:
        break
clientsocket.send(data)

这似乎也产生相同的结果。有没有更有效的方法从 proc.stdout.readline 读取所有数据?

python-3.x subprocess stdout
3个回答
1
投票

我也遇到过同样的问题。奇怪的是,在 Python 2.7 中,它没有收敛问题,而且实际上停止了迭代。 在调试期间(在 Python 3.5 中),我注意到所有真正的行都以

'\n'
字符返回,而原本不应该到达的行则作为空字符串返回,即
''
。所以,我只是添加了一个 if 子句来检查
''
,如果为正则中断循环。
我的最终版本如下:

lines = []
for _line in iter(process.stdout.readline, b''):
    if _line == '':
        break
    lines.append(_line)

可能值得一提的一件事是,我在

universal_newlines=True
调用时使用了
subprocess.Popen(..)
参数。


0
投票

语句:

iter(proc.stdout.readline, "")
将执行阻塞读取,直到收到 EOF。

如果你想阅读所有行,那么你可以这样做:

data = b''
data = b"".join(proc.stdout.readlines())

除了让

proc
更快地生产线条之外,没有其他解决方案。 如果需要,您可以超时读取行(即您可以等待读取选定数量的字符,或者如果未读取该数量的字符则超时)。

这些答案可以在这里找到:


0
投票

我还在一些

iter(p.stdout.readline, b'')
任务中遇到了
subprocess.Popen
永远卡住的问题。

那些突破

iter
的技巧(123)都不起作用。

我最终发现这是因为

stderr
也有输出但从未被读取,导致无限等待和挂起。

要解决这个问题,您需要阅读这两本。代码片段来自 Dev Aggarwal 和 Deepak Yadav 此处:

import sys import selectors def popen_reader(p: subprocess.Popen) -> tuple: sel = selectors.DefaultSelector() sel.register(p.stdout, selectors.EVENT_READ) sel.register(p.stderr, selectors.EVENT_READ) done = False while not done: for key, _ in sel.select(): data = key.fileobj.read1().decode() # noqa # ignore "Cannot find reference 'read1' in 'int | HasFileno'" if not data: done = True break if key.fileobj is p.stdout: print(data, end="") else: print(data, end="", file=sys.stderr) return p.wait()
    
© www.soinside.com 2019 - 2024. All rights reserved.