2011-12-13 64 views
4

我有一个问题...有谁知道为什么这个代码挂在while循环。循环似乎没有捕捉到标准输出的最后一行。python popen.stdout.readline()挂起

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

会在这里猜测,但我发现,p.stdout.read *()将始终是一个阻塞调用,如果没有任何数据要返回,那么它会一直阻塞。非阻塞阅读可能会帮助你。 – 2011-12-13 20:43:25

+0

冒着听起来像一个大白痴的风险,你可以解释你通过非阻塞阅读,因为:) :) – 2011-12-13 20:46:40

回答

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)