2011-12-13 345 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)