2012-09-28 8 views
8

コンテキスト:特定のコマンドを実行した後、Pexpectが断続的にハングする(EOFを検出しない)のはなぜですか?

私はその仕事コマンドの「ライブ」出力を与えることですpexpectを、使用して書かれたいくつかのコードを持っています。私。コマンドが完了するまで待ってから出力と対話するのではなく、コマンドが何らかの出力を生成したときに、またはすぐ後に何かを出力する。

私がやっていることは、サービスの開始と停止です。私は、プロセスをINGの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秒後には必ずしも4-6の後に歯ぐきになります(したがって、delステートメント;私はそれを安全にプレイすると思っていました)。

のPython 2.6.6、CentOSの(64)6.3、Pexpect 2.3-6、FWIW

質問:

なぜpexpectは、特定のコマンドの上にぶら下がっていますか?この問題をどのように解決すればよいですか? タイムアウトを使用することは現実的な解決策ではありません。これらのコマンドのうちのいくつかは実際には任意の長時間実行できます。 service zend-server stopは、私が例を挙げて選んだものです。それはそれほど時間がかかりませんので、私はそれを終わらせることができます。

を私はexpect('\n')を使用して、次の、とwatch方法を交換しようとしましたが、結果は同じです:再起動の可変数、そして最終的にハング私が試した何

\nと一緒に配列にpexpect.EOFを追加し、戻り値を処理してループから抜け出すこともできますが、それでも同じ場所でハングします。

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 
+1

を渡すことで、バッファリングを無効にすることができます。なぜサブプロセスと対話していないときに 'pexpect'を使用していますか?出力にのみ関心があるならば、stdlibの 'subprocess'で十分です。 –

+1

これは簡単な例です。プロダクションバージョンでは、 'expect 'などの呼び出しがありますが、私が提出した抜粋された例は、それ自身で正しく動作しません。 –

+1

このコードを使用して問題を再現することはできません。コードが問題であるかどうかはわかりません。多分あなたはzendサーバーから何の出力も得ていないでしょうか? – aychedee

答えて

2

pexpectがより多くのデータを待っているバッファリングの問題のように見えます。 maxread=1pexpect.spawn()

+0

効果はありませんが、良いアイデアです! –

関連する問題