python popen.stdout.readline()挂起

时间:2011-12-13 20:33:07

标签: python stdout popen

我有问题...有谁知道为什么这段代码在while循环中挂起。循环似乎没有捕获标准输出的最后一行。

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

line = working_file.stdout.readline()
working_file.stdout.flush()
while working_file != "" :
    print(line)
    line = working_file.stdout.readline()
    working_file.stdout.flush()

当遇到readline()时,脚本会随着光标一样闪烁。我不明白为什么。任何人都可以解释一下

全部谢谢

乔恩

1 个答案:

答案 0 :(得分:4)

执行非阻塞读取会帮助您吗?

import fcntl
import os

def nonBlockReadline(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.readline()
    except:
        return ''

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

line = nonBlockReadline(working_file.stdout)
working_file.stdout.flush()
while working_file != "" :
    print(line)
    line = nonBlockReadline(working_file.stdout)
    working_file.stdout.flush()

我不确定你到底想要做什么,但这会更好吗?它只读取所有数据,而不是一次只读取一行。它对我来说更具可读性。

import fcntl
import os

def nonBlockRead(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.read()
    except:
        return ''

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

stdout = ''

while working_file.poll() is None:
    stdout += nonBlockRead(working_file.stdout)

# we can probably save some time and just print it instead...
#print(stdout)

stdout = stdout.splitlines()
for line in stdout:
    print(line)

编辑:一个更适合您的用例的通用脚本:

import fcntl
import os

def nonBlockRead(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.read()
    except:
        return ''

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

while working_file.poll() is None:
    stdout = nonBlockRead(working_file.stdout)

    # make sure it returned data
    if stdout:
        # process data
        working_file.stdin.write(something)