上下文
我有一些使用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")
此代码应该只循环服务:启动它并反复停止它,打印开始/停止的输出。它打印输出正常。但是,它最终会在“OUT 2”之前挂起。我可以查看输出,并看到service
调用停止执行。然而,watch
函数从未提升EOF并退出。
每项服务都不会发生这种情况。有些服务无限循环。但是,zend-server
以及其他一些不相关的命令会以相同的方式间歇性地失败。
通过“最终挂起”,我的意思是它启动/停止服务一些(每次运行变量)次,然后挂起。它通常在4-6之后长大,虽然从来没有在第一次调用 - 总是至少在第二次(因此del
语句;我认为我会安全地玩它)。
Python 2.6.6,CentOS(64)6.3,Pexpect 2.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
答案 0 :(得分:3)
看起来像一个缓冲问题,其中pexpect正在等待更多数据。您可以尝试通过将maxread=1
传递给pexpect.spawn()