環境:
を使用して記述されたコードがいくつかあります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
ただし、他のいくつかの無関係なコマンドとともに、同じように断続的に失敗します。
「最終的にハングする」とは、サービスを数回 (実行ごとに可変) 開始/停止し、ハングすることを意味します。それは通常、最初の呼び出しでは決してありませんが、少なくとも 2 番目の呼び出しでは常に 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