3

我一定忽略了一些非常明显的东西。我需要执行一个 C 程序,实时显示它的输出,最后解析它的最后一行,这应该很简单,因为打印的最后一行总是相同的。

process = subprocess.Popen(args, shell = True,  
                           stdout = subprocess.PIPE, stderr = subprocess.PIPE)

# None indicates that the process hasn't terminated yet.
while process.poll() is None:

    # Always save the last non-emtpy line that was output by the child
    # process, as it will write an empty line when closing its stdout.
    out = process.stdout.readline()
    if out:
        last_non_empty_line = out

    if verbose:
        sys.stdout.write(out)   
        sys.stdout.flush()

# Parse 'out' here...

但是,有时不会打印最后一行。Popens 的bufsize的默认值为0,因此它应该是无缓冲的。我也尝试在退出之前将fflush(stdout)添加到 C 代码中,但无济于事,但似乎完全没有必要在退出程序之前刷新流。

任何人的想法?

4

2 回答 2

3

问题是您正在读取行,直到进程退出,(process.poll()),而由于 shell 标志,您确实使用了缓冲。

您必须继续阅读 process.stdout 直到到达文件末尾或空行。

于 2010-03-12T12:36:23.823 回答
2

readline()必须缓冲文本,等待换行。

您将始终遇到竞争条件 - 没有多少未缓冲的流将处理您正在处理一行,然后检查退出,然后读取一行的事实,因此如果子进程在您处理一行时退出,您将不会阅读其他任何内容。此外,外壳可能正在引入自己的缓冲。

所以你可以:

  1. 在子进程运行时使用communicate()并放弃详细输出。

  2. 确保在进程退出后继续阅读,直到获得 EOF。

我还建议更改您的代码,以便您不必使用shell=True.

于 2010-03-12T12:34:14.400 回答