2012-11-15 10 views
16

だから私はsubprocess.callに気づき、pythonスクリプトを実行する前にコマンドが終了するのを待っています。subprocess.Popen以外のstdoutを得る方法はありません。終了するまで待つ代替関数呼び出しがありますか?Python subprocess.callとsubprocess.Popen stdout

HIHIHI 

は注:私はこれでwineを実行しようとしています、私は私の出力os.systemコール

result = subprocess.Popen([commands..., 
         self.tmpfile.path()], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = result.communicate() 
print out+"HIHIHI" 

を避けるためにしようとしている:

NOTE(私もPopen.waitを試してみました)。

+1

* subprocess.call()*を使用して/ errを読み取ることができます。 [マニュアルを確認してください](http://docs.python.org/2/library/subprocess.html)。コマンドが大量の出力を生成しないことを確認してください。 – tuxuday

答えて

46

shell=Trueを避けたいと思うかもしれませんが、私は次の構成を使用しています。これは、同様にあなたに任意のコマンドの出力とエラーメッセージ、およびエラーコードを示します:

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

# wait for the process to terminate 
out, err = process.communicate() 
errcode = process.returncode 
+0

私はこれを試みましたが、私はまだ空の結果を得ています。 –

+2

'cmd'の内容は何ですか? – Alex

+0

@Alex cmdは、実行するコマンドでなければなりません。 – NeoMorfeo

10

あなたのプロセスは、巨大なstdoutとなし標準エラー出力を与える場合は、communicate()が、メモリ制限のために行くには間違った方法かもしれません。

代わりに、

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

# wait for the process to terminate 
for line in process.stdout: do_something(line) 
errcode = process.returncode 

は、移動するための方法かもしれません。

process.stdoutは主に、あなたが他のどのようなオブジェクトとして扱うことができ、ファイルのようなオブジェクトです:

  • することができますあなたが反復処理することができます
  • あなたはそれからreadline()でき
  • それからと read()それ。

後者は、その内容を1行ずつ取得するために私が上で行ったことです。

+1

forループが何をしているのか説明できますか? –

+0

@ Stupid.Fat.Catプロセスから生成された 'stdout'を1行ずつ読み込み、各行を処理します。 – glglgl

+0

'LineEffect.stdout'の操作で' ValueError:I/O操作を閉じたファイル 'を取得しました – Yash89

11
subprocess.check_output(...) 

プロセスを呼び出し、エラーコードが0以外であれば発生し、それ以外の場合はstdoutを返します。それはちょっと速記だから、PIPEやものについて心配する必要はありません。

+0

これは私が信じる 'ワイン'に問題がある。申し訳ありませんが、私はそれを私の質問に追加します。 –

+3

これはPython 2.7以降での素晴らしい機能です。 – Gourneau

1

私はのような何か試してみた:つまり...

#!/usr/bin/python 
from __future__ import print_function 

import shlex 
from subprocess import Popen, PIPE 

def shlep(cmd): 
    '''shlex split and popen 
    ''' 
    parsed_cmd = shlex.split(cmd) 
    ## if parsed_cmd[0] not in approved_commands: 
    ## raise ValueError, "Bad User! No output for you!" 
    proc = Popen(parsed_command, stdout=PIPE, stderr=PIPE) 
    out, err = proc.communicate() 
    return (proc.returncode, out, err) 

は(shlex.splitを聞かせて)ほとんどの作業を行います。シェルのコマンドラインを解析したり、パイプ演算子を見つけたり、独自のパイプラインを設定しようとはしません。もしあなたがそれをやろうとするなら、基本的に完全なシェルシンタックスパーサーを書かなければならないでしょう。そして、あなたはひどく多くの配管作業を終わらせます。もちろん

これは疑問、なぜちょうどシェル= Trueの(キーワード)オプションでpopenのを使用しないを上げますか?これにより、シェルに文字列(分割も解析もしない)を渡すことができ、望むように結果を集めることができます。ここの私の例では、コマンドに含まれる可能性のあるパイプライン、バッククォート、ファイル記述子のリダイレクションなどは処理されません。コマンドのリテラル引数として表示されます。したがって、それはまだシェル=真で実行してより安全です ...私はコマンドをある種の「承認されたコマンド」辞書またはセットに照らしてチェックするという馬鹿げた例を与えてきました。それ以前に引数を正規化することを要求しない限り、絶対パスに正規化するほうが意味があります。コマンド文字列をこの関数に渡します。

+0

私はこの例が好きです。コマンドライン入力を解析する適切な方法としてshlexに注目しています。この例のユーモアも(shlep()と例外コメント)。 :) –

関連する問題