2009-03-29 14 views
6

これは単純なpythonの質問ですと思います。なぜ、subprocess.Popen(...)が返されないのですか?

私はPythonインタプリタで次の操作を試してください。

>>> import process 
>>> def test(cmd): 
... p = subprocess.Popen(cmd) 
... 
>>> test(['ls', '-l']) 

それはls -lを実行しますが、私は新しい>>>プロンプトを取得するには、「リターン」をヒットする必要があります。しかし

、私は次のことを試してください。

>>> import process 
>>> def test(cmd): 
... p = subprocess.Popen(cmd) 
... p.wait() 
... 
>>> test(['ls', '-l']) 

その後ls -lは>>>プロンプトすぐに存在して実行されます。

もう一つのバリエーション:

>>> import process 
>>> def test(cmd): 
... p = subprocess.Popen(cmd, stdout=subprocess.PIPE) 
... 
>>> test(['ls', '-l']) 

これは私にすぐに新しいプロンプトを与えます。

最後の例は、私が欲しいものに最も近い例です。私の目標は子プロセスを起動し、それが完了するのを待ってから、親プロセスでstdoutを使用します。p.stdoutを参照し、stderrを他の場所に印刷するだけです。

実際のアプリケーションでは、 p = subprocess.Popen(cmd, stdout=subprocess.PIPE)には、p.wait()の有無にかかわらず、最後のバージョンがハングアップするだけです。

おかげで、

チャーリー

答えて

7

私は自分の質問に答えている可能性があります。私は最後のケースでは、プロセスを継続するためにp.stdoutから明示的に読む必要があると確信しています。

すなわち:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE) 
output = p.stdout.readlines() 
.... 

おかげで最初のバリエーションでは、すべての

8

を、test()戻ってすぐにプロセスを開始した後、その出力はコンソールに送信される前に。

あなたは出力を見ればあなたがを行うはすぐlsの出力前に、プロンプトを取得します。第二の変形例で

>>> test(['ls', '-l']) 
>>> total 0       <----- test() returns, new propmpt 
--rw-r--r-- 1 foo bar 7 Mar 24 17:38 
etc etc 

test()は、それが戻る前に終了する処理を待っています。

3番目のバージョンでは、子プロセスのstdoutを読み込んで続行する必要があります。

0

ただ通信()メソッドを使用してください。返す必要はありません。

>>> test(['ls', '-l']) 
>>> 
>>> def test(cmd): 
... p = subprocess.Popen(cmd).communicate() 
... 
>>> test(['ls', '-l']) 
+1

サブコマンドの標準ハンドラをリダイレクトしないと、 '.communicate()'は何も役に立ちません。それを 'wait()'呼び出しで置き換えるほうがよいかもしれません。 – glglgl

0

ここでは、Googleに永久にpingするコマンドがあるため、出力を取得するには手動で終了する必要があります。

os.popen()メソッド呼び出しを完全なsubprocess.Popenクラスに変換する方法については、subprocess documentationを参照してください。

host = "www.google.com" 
command = "ping %s -t"%host 

#p = os.popen(command) -- using Popen instead of os.popen() to allow calling terminate() 
p = Popen(command, stdout=subprocess.PIPE) 

time.sleep(5) 
print "term" 
p.terminate() 
pingResultSoFar = p.communicate()[0] # get what has been printed to standard out so far 
print pingResultSoFar 
関連する問題