[英]printing stdout pipe of sub processes ignore last lines
我正在尝试运行一个子进程并观察他的标准输出,直到找到所需的字符串。 这是我的代码:
def waitForAppOutput(proc, word):
for stdout_line in iter(proc.stdout.readline, b''):
print stdout_line
if word in stdout_line.rstrip():
return;
p = Popen(["./app.sh"], shell=True, stdin=PIPE ,stdout=PIPE, stderr=PIPE)
waitForAppOutput(p,"done!")
这里的问题是,由于某种原因,function waitForAppOutput
在“完成”之前停止打印标准输出几行。 这是应该出现在 stdout 中的最后一行。 我假设iter(proc.stdout.readline, b'')
被阻塞并且readline
无法读取标准输出的最后几行。
知道这里有什么问题吗?
你有一个拼写错误:它应该是waitForAppOutput
而不是waitForAppOutout
。 这甚至是如何运行的? 当您使用 shell 调用命令时,您不应该传递字符串数组,而是传递一个字符串。
通常应该在Popen
调用的返回子进程 object 上使用communicate
方法来防止潜在的死锁(这似乎是您正在经历的)。 这将返回一个元组: (stdout, stderr)
, stdout
和stderr
output 字符串:
from subprocess import Popen, PIPE
def waitForAppOutput(stdout_lines, word):
for stdout_line in stdout_lines:
print stdout_line
if word in stdout_line.rstrip():
return;
p = Popen("./app.sh", shell=True, stdout=PIPE, stderr=PIPE, stdin=PIPE, universal_newlines=True)
expected_input = "command line 1\ncommand line 2\n"
stdout, stderr = p.communicate(expected_input)
stdout_lines = stdout.splitlines()
waitForAppOutput(stdout_lines, "done!")
唯一的问题是 output 字符串是否很大(无论您对大的定义可能是什么),因为将整个 output 读取到 ZCD69B4957F06CDE218D7BF3D61980 中可能会导致内存效率低下甚至令人望而却步。 如果这是您的情况,那么我会尝试通过仅管道stdout
来避免死锁。
from subprocess import Popen, PIPE
def waitForAppOutput(proc, word):
for stdout_line in iter(proc.stdout.readline, ''):
print stdout_line
if word in stdout_line.rstrip():
return;
p = Popen("./app.sh", shell=True, stdout=PIPE, stdin=PIPE, universal_newlines=True)
expected_input = "command line 1\ncommand line 2\n"
p.stdin.write(expected_input)
p.stdin.close()
waitForAppOutput(p, "done!")
for stdout_line in iter(p.stdout.readline, ''):
pass # read rest of output
p.wait() # wait for termination
更新
这是一个使用这两种技术的示例,该技术运行 Windows sort
命令来对一堆输入行进行排序。 这两种方式都特别有效,因为排序命令在读取所有输入之前不会启动 output,因此它是一个非常简单的协议,其中很容易避免死锁。 尝试在USE_COMMUNICATE
交替设置为True
和False
的情况下运行它:
from subprocess import Popen, PIPE
USE_COMMUNICATE = False
p = Popen("sort", shell=True, stdout=PIPE, stdin=PIPE, universal_newlines=True)
expected_input = """q
w
e
r
t
y
u
i
o
p
"""
if USE_COMMUNICATE:
stdout_lines, stderr_lines = p.communicate(expected_input)
output = stdout_lines
else:
p.stdin.write(expected_input)
p.stdin.close()
output = iter(p.stdout.readline, '')
for stdout_line in output:
print stdout_line,
p.wait() # wait for termination
印刷:
e
i
o
p
q
r
t
u
w
y
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.