Python:subprocess32 process.stdout.readline()等待时间

如果我使用例如“ls -Rlah /”运行以下函数“run”,我会立即通过print语句获得输出

import subprocess32 as subprocess
def run(command):
    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT)
    try:
        while process.poll() == None:
            print process.stdout.readline()
    finally:
        # Handle the scenario if the parent
        # process has terminated before this subprocess
        if process.poll():
            process.kill()

但是,如果我使用下面的python示例程序,它似乎停留在process.poll()或process.stdout.readline()上,直到程序完成.我认为它是stdout.readline(),因为如果我将输出的字符串数量从10增加到10000(在示例程序中)或者在每次打印后添加到sys.stdout.flush()中,则在运行中打印函数确实被执行了.

如何使子进程的输出更加实时?

注意:我刚刚发现python示例程序在输出时不执行sys.stdout.flush(),是否有一种方法让子进程的调用者以某种方式强制执行此操作?

每5秒输出10个字符串的示例程序.

#!/bin/env python
import time

if __name__ == "__main__":

    i = 0
    start = time.time()
    while True:
        if time.time() - start >= 5:
            for _ in range(10):
                print "hello world" + str(i)
            start = time.time()
            i += 1
        if i >= 3:
            break

最佳答案 您应该在脚本中刷新标准输出:

print "hello world" + str(i)
sys.stdout.flush()

当标准输出是终端时,stdout是行缓冲的.但是当它不是时,stdout是块缓冲的,你需要显式刷新它.

如果无法更改脚本的源代码,可以使用Python的-u选项(在子进程中):

-u     Force stdin, stdout and stderr to be totally unbuffered. 

你的命令应该是:[‘python’,’ – u’,’script.py’]

通常,这种缓冲发生在用户空间中.没有通用的方法来强制应用程序刷新其缓冲区:某些应用程序支持命令行选项(如Python),其他应用程序支持信号,其他应用程序不支持任何内容.

一种解决方案可能是模拟伪终端,给程序提供“提示”,它们应该在行缓冲模式下运行.尽管如此,这并不是一个适用于所有情况的解决方案.

点赞