繁体   English   中英

打印子进程的标准输出 pipe 忽略最后几行

[英]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)stdoutstderr 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交替设置为TrueFalse的情况下运行它:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM