2009-05-19 8 views
4

は、私がこれを書い言う:私はsubprocess.Popenから返されたファイルハンドルをポーリングする方法はありますか?

line = p.stdout.readline() 

をすれば、サブプロセスは、次の行を出力するまで

from subprocessing import Popen, STDOUT, PIPE 
p = Popen(["myproc"], stderr=STDOUT, stdout=PIPE) 

は今、私のプログラムを待ちます。

私がp.stdoutに行うことができる魔法はありますか?それがあれば出力を読むことができますが、それ以外の場合はそのまま続行できますか? Queue.get_nowait()

私はちょうどp.stdoutを読むためのスレッドを作成できますが、私は新しいスレッドを作成できないとしましょう。

答えて

5

http://docs.python.org/library/select.htmlを参照して、Pythonの標準ライブラリにselectモジュールを使用してください。 select.select([p.stdout.fileno()], [], [], 0)は、すぐにその項目が3つのリストであるタプルを返します。最初のものは、そのファイル記述子で読み込むものがあれば空ではありません。

+0

+1私はこの解決策が好きです –

+0

正確に何が返されますか?これは、読み込むためにどれくらいのバイト数があるかという手がかりをまだ与えていません。 – iElectric

+2

'select'は、ブロックせずにI/Oを実行できるファイル記述子のセット(あなたが渡したファイル記述子のセット)を返します。事実(システムに依存する)の後にp.stdoutをnon-blockingに設定することができれば、いくつかの大きなNに対してはp.stdout.read(N)だけで、実際に利用可能なすべてのバイトを得ることができます。ノンブロッキングオプションが利用できない場合は、一度に1バイトずつ読み込み、それ以上がないことを示すまで「選択」に戻ります。読み込んだバイトを必ずリストに追加し、最後に ".join"を追加してください(文字列に+ = 'ng離れているよりはるかに速い!)。 –

8

使用p.stdout.read(1)これは文字

で文字を読み、ここに完全な例であるだろう。

import subprocess 
import sys 

process = subprocess.Popen(
    cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE 
) 

while True: 
    out = process.stdout.read(1) 
    if out == '' and process.poll() != None: 
     break 
    if out != '': 
     sys.stdout.write(out) 
     sys.stdout.flush() 
+0

ありがとうございます!私はこの問題に簡単な答えを尋ねたことが何回目にあるのか分かりません。私もキャラクターでキャラクターを読もうとしていましたが、プロセスが完了したかどうかをチェックする方法はわかりませんでした。 +1 – jkp

+1

+1この解決策は、 'subprocess'モジュールによって作成されたファイル記述子で' select'が動作しないWindows上では適切かもしれません。注意:サブプロセスがstderrに十分な出力を生成した場合、それを読み取らないとブロックする可能性があります(OPはstderrをstdout(stderr = STDOUT')にリダイレクトします。 'なし'と比較するには 'is'を使用します。たとえば' xがNoneでない場合 'などです。 'if out!= '':'の代わりに 'if out:'を使うことができます(バイト文字列とUnicode文字列の両方で動作します)。また、 'cmd'が非対話モードでブロックバッファリングを使用する場合、' process.stdout'は 'cmd'がバッファをフラッシュするまで何も取得しません。 – jfs

+2

私はこれが質問された質問に答えるとは思わない。このメソッドは、利用可能な出力がない場合、read(1)でブロックします。要求されたのは、その場合ブロックしないで、代わりに何か他の処理を行うメソッドでした。 –

関連する問題