2013-02-06 15 views
9

私はPythonスクリプトからJavaプログラムを呼び出しています。私は欲しくないたくさんの無駄な情報を出力しています。私はPopen関数にaddind stdout=Noneを追加しようとしました:subprocess.Popenからの出力を無視します。

subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=None) 

同じことをします。何か案が? documentationから

答えて

31

標準入力、stdoutとstderrは、標準で実行されるプログラムの標準入力を指定します出力ファイルハンドルと標準エラーファイルハンドルをそれぞれ出力します。有効な値は、PIPE、DEVNULL、既存のファイル記述子(正の整数)、既存のファイル・オブジェクト、およびなしです。

ので:

subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=subprocess.DEVNULL) 

これは3.3以降に存在します。しかし、ドキュメントには次のように書かれています。

DEVNULLは、特別なファイルos.devnullが使用されることを示します。

os.devnullは、(subprocessが存在する前に)2.4に戻って存在します。だから、あなたは手動で同じことを行うことができます。

with open(os.devnull, 'w') as devnull: 
    subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=devnull) 

注意を使用すると、単一の行に収まらない、より複雑な何かをやっている場合、あなたはPopenの全体の生命のためのオープンdevnullを維持する必要があることオブジェクトだけでなく、その構造。 (これはwith文の中全体を置く、である。)

/dev/null(POSIX)またはNUL:(Windowsの場合)にリダイレクトすることの利点は、より重要なのは、することができますが、不要なパイプを作成していないということである、と」サブプロセスがそのパイプへの書き込みをブロックするエッジケースに入る。

理論的には、subprocessは、os.devnullのプラットフォームでは動作しない可能性があります。 CPythonをPOSIXやWindows、PyPy、Jython(あなたの大部分)だけに気にするなら、決して問題にはなりません。それ以外の場合は、コードを配布する前にテストしてください。

+0

+1:devnullの場合。サブプロセスが生きている間は、 'devnull'が開いたままであることを確認してください(with文はそうでないことを意味します)。最後の段落は不要です:DEVNULLはCPythonのos.devnullを介して実装されています。 os.devnullはJythonで動作します。 – jfs

+0

@ J.F.Sebastian: 'check_call'(' with'の中にある)の後に 'devnull'は必要なくなりました。しかし、ええ、たぶん、私は、単一の行に収まらないより複雑なユースケースについては、 'Popen'だけでなく' with'の中にすべてのものを入れる必要があることを明確にすべきです。 – abarnert

+0

@JFSebastian:一方、 'os.devnull'の場合、'サブプロセス 'が存在するすべてのプラットフォームに実際に存在することが保証されているので、 "使用前にチェックする"必要はありません。 Jython上で確認する必要のないプラットフォームのリストにJythonを移動する必要がありますか? – abarnert

6

Noneのデフォルト設定では

、何のリダイレクトは発生しません。

あなたは.communicate()を呼び出し、単に撮影した出力を無視し、その後、subprocess.PIPEからstdoutを設定する必要があります。

p = subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
p.communicate() 

私はあなたのニーズに十分応えよりsubprocess.call()以上を使用している疑いがあるものの:3.3 documentationから

subprocess.call(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
+1

@sjtaheri:訂正ありがとう、私はそれを自分で適用しました。 –

+4

パイプの作成と無視は通常動作しますが、あまりにも多くの書き込みをすると、子プロセスがブロックされることがあります(もちろん、システム上で動作し、ユーザーの1人に失敗する可能性があります)コミュニケーションの代わりにここで単に呼び出すだけで安全です。これは、 'DEVNULL'が追加された理由です。あなたが'電話するだけで、心配する必要はありません。 (これはちょっと複雑なケースで、 'stderr = DEVNULL'を設定しますが、' stdout'と 'check_output'だけを設定しています)。 – abarnert

+0

@abarnert:ああ、それが追加された;ちょうどPython 3のドキュメントでそれを見つけました。 –

関連する問題