上下文:
我有一些用pexpect编写的代码,它的工作是提供命令的“实时”输出。也就是说,当一个命令生成某个输出时,或者之后不久,就打印出来,而不是等到命令完成后再与其输出交互。
我所做的就是开始和停止一项服务。我这样做是通过对流程进行spawn,然后在打印时输出每一行,如下所示:
def watch(process):
output = ""
while True:
try:
line = process.read_nonblocking(timeout = -1)
print(line, end ="")
output += line
except pexpect.EOF:
break
del process
return output
while True:
print("IN 1")
process = pexpect.spawn("service",["zend-server", "stop"], timeout = None)
watch(process)
print("OUT 1")
print("IN 2")
process = pexpect.spawn("service",["zend-server", "start"], timeout = None)
watch(process)
print("OUT 2")这段代码应该只循环服务:启动它并一次又一次地停止它,打印开始/停止的输出。它把输出打印得很好。然而,它最终挂在“出局2”之前。我可以查看输出,并看到service调用停止其执行。然而,watch函数从不引发EOF并退出。
并不是每个服务都会发生这种情况。有些服务无限期地循环。然而,zend-server以及其他一些不相关的命令也以同样的方式间歇性地失败。
所谓“最终挂起”,我的意思是它启动/停止服务几次(每次运行时都是变量),然后挂起。它通常在第4-6之后就开始运行,虽然在第一次调用时从来没有--至少在第二次调用时是这样的(因此出现了del语句;我想我应该谨慎行事)。
Python2.6.6,CentOS (64) 6.3,PExp2.3-6,FWIW
问题:
为什么pexpect要挂在某些命令上?我该如何解决这个问题呢?使用超时并不是一个可行的解决方案,因为其中一些命令确实可以运行任意长时间。service zend-server stop只是我选择的一个例子,因为它不需要那么长的时间,我可以观察它的完成。
我尝试过的:
我尝试用以下方法替换watch方法,该方法使用expect('\n'),但结果是相同的:重新启动的变量数,然后是最终挂起。
我还可以将pexpect.EOF添加到expect和\n的数组中,并处理返回值以脱离循环,它仍然挂在相同的位置。
def watch2(process):
output = ""
done = False
while True:
try:
if not process.isalive():
line = process.readline()
done = True
else:
process.expect(['\n'])
line = process.before
print(line)
output += line
if done:
raise pexpect.EOF(0)
except pexpect.EOF:
break
del process
return output发布于 2012-11-19 23:09:34
看起来像一个缓冲问题,在这里pexpect正在等待更多的数据。您可以尝试通过将maxread=1传递给pexpect.spawn()来禁用缓冲。
https://stackoverflow.com/questions/12647212
复制相似问题