python popen.stdout.readline() 卡住
我遇到一个问题……有没有人知道为什么这段代码在while循环里卡住了?这个循环似乎没有处理到stdout
的最后一行。
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 个回答
7
你在做非阻塞读取的时候,有帮助吗?
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)