2009-03-30 5 views
44

呼び出されたときに出力を生成するAという名前のバイナリがあります。私がBashシェルから呼び出すと、出力のほとんどはA > /dev/nullに抑止されます。すべての出力が抑制されますA &> /dev/null実行ファイルへのPython呼び出しの出力を抑制する

私はAを呼び出す必要があるBという名前のpythonスクリプトを持っています。私はBからの出力を生成することができ、Aからのすべての出力を抑制したいと考えています。 B内から

、「BのすべてのIはos.system('A')os.system('A > /dev/null')、およびos.system('A &> /dev/null')os.execvp('...')、などを試してみたが、それらのどれも私がB &> /dev/nullを実行することができA.

からのすべての出力を抑制しないが、それは抑制します私はそれを望んでいません。

誰でもお勧めしますか?

答えて

57

、あなたはthe subprocess moduleを使用することができます。コマンドは引数を持たない

>>> import subprocess 
>>> s = subprocess.Popen(['cowsay', 'hello'], \ 
     stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0] 
>>> print s 
_______ 
<hello> 
------- 
     \ ^__^ 
     \ (oo)\_______ 
      (__)\  )\/\ 
       ||----w | 
       ||  || 
+0

私はこれを試して、それは働いて、ありがとう! – Lin

+57

+1 for cowsay :) – MestreLion

+7

これは、stdoutへの出力が制限されていないとうまく動作しません。 –

8

os.system()ドキュメントには、subprocessモジュールを使用し、必要に応じてstdout = open(os.devnull、 'w')(stderrの場合も同じ)を設定します。サブプロセス。あなたは、Python 2.4を使用している場合

103
import os 
import subprocess 

command = ["executable", "argument_1", "argument_2"] 

with open(os.devnull, "w") as fnull: 
    result = subprocess.call(command, stdout = fnull, stderr = fnull) 

場合は、あなただけの単純な文字列としてそれを提供することができます。

コマンドがワイルドカード、パイプ、環境変数などのシェル機能に依存する場合は、コマンド全体を文字列として指定し、shell = Trueも指定する必要があります。ただし、文字列の内容が慎重に検証されていないとセキュリティ上の危険があるため、これは避けるべきです。

+0

なぜshell = Trueですか? –

+4

元の質問はos.systemを使用していて、彼がやっていることを正確に知らないので、shell = Trueが最も信頼できる翻訳です。 – DNS

+0

DNS、私はあなたのソリューションを試して、それは私のために完全に動作します。ありがとう! – Lin

1

私はそれがゲームに遅れていることは知っていますが、単にos.systemの中から/ dev/nullに出力をリダイレクトしないのはなぜですか?例:

これは、subprocess.STDOUTを処理したくない場合に有効です。

+2

システム・コールにos.systemを使用することは推奨されていません。サブプロセスモジュールはそれをよりエレガントで安全な方法で処理します – MestreLion

12

検索エンジンが私のようなこの古い質問につながった場合は、PIPEを使用するとデッドロックが発生する可能性があることに注意してください。 実際、パイプはバッファリングされているので、誰もそれを読んでいなくても、パイプに一定数のバイトを書き込むことができます。しかし、バッファのサイズは有限です。したがって、プログラムAがバッファより大きな出力を持つ場合、呼び出しプログラムBがAの終了を待つ間に、Aは書き込み時にブロックされます。ただし、この特定の場合は...下記のコメントを参照してください。

まだ、私はDevin JeanpierreとDNS 'ソリューションを使用することをお勧めします。

私が使用
+0

これは本当に正しいですか? call()またはpopen()/ wait()を使用してpopen()/ communicate()を使用しないと、デッドロックしか発生しないと思います。 –

+0

はい!ドキュメントを引用するには、 "メモデータはメモリにバッファされているので、データサイズが大きい場合や無制限の場合はこのメソッドを使用しないでください。" –

+0

"メモリにバッファされています"とは必ずしもパイプがデッドロックしているとは限りません。それらがdocsで参照する問題は、コマンドが多くの出力を生成すると、すべてがpythonのヒープ上のメモリに格納されるということです。もちろん、これは望ましくないことであり、メモリ不足エラーや非常に悪い結果を招くこともありますが、極端な場合にのみ、デッドロックは発生しません。 – Clueless

0

call(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 
コマンドは、コマンドの文字列である

+引数

をあなただけのSTDOUTをキャプチャする必要がある場合は、サブプロセス

+1

デッドロックしませんか? –

0

をインポートする必要があり、これが機能するためには、」doesnのそれを変数に代入するのはこれですか?たとえば:

megabyte='' 
# Create a 1 MiB string of NULL characters. 
for i in range(1048576): 
    megabyte += '\0' 
fh=open('zero.bin','w') 
# Write an 8 GiB file. 
for i in range(8192): 
    print(i) 
    # Suppress output of 'write()' by assigning to a variable. 
    discard=fh.write(megabyte) 
fh.close() 

私は私のハードドライブ上のゼロの空き領域に大きなゼロで満たされたファイルを作成し、handle.writeするために、各コール(文字列)が書き込まれたバイト数を吐き出すことが発見されました。それをバイラブルに割り当てることは、その出力を抑制した。

21

Python 3.3以降では、subprocessan option for redirecting to /dev/nullをサポートしています。それを使用するには、.Popenと友人を呼び出すときは、キーワード引数としてstdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,を指定してください。

だから、Pythonの3.3+のために書き換えDNSの答えは、ドキュメントから

import subprocess 
command = ["executable", "argument_1", "argument_2"] 
result = subprocess.call(command, 
         stdout=subprocess.DEVNULL, 
         stderr=subprocess.DEVNULL) 

次のようになります。

subprocess.DEVNULL¶

標準入力として使用することができる特別な値、 stdoutまたはstderr Popenの引数であり、特別なファイルos.devnullが を使用することを示します。

バージョン3.3の新機能。 3.2へのPython 3.0の場合

DNSが書いたように、あなたは、手動でopen(os.devnull)を使用してヌルデバイスを開く必要があります。

+1

残念ながら、 'subprocess.DEVNULL'は3.3+でのみ利用可能です。この回答は、互換性コード(またはそれへの参照)で修正する必要があります。 'shell = True'を使う理由もありません。 – phihag

+0

@phihag:DNSの答えが 'subprocess.DEVNULL'なしでそれを行う方法を適切に記述しているので、私は互換コードを含めていませんでした。あなたは 'シェル'について正しいです。一定。 –

+0

これは私のために働いたpython3 –

0

バックアップタスクの開始などのコマンドが完了するのを待たずに、別のオプションをbashに渡してリダイレクトを正常に動作させることもできます。例えば

、はaplayを使用して、サウンドファイルの開始:私は新しいプロセスを生成することができますこの方法は、端末に印刷するから、それを終了し、停止するのを待たない、

import os 

def PlaySound(filename): 
    command = 'bash -c "aplay %s &> /dev/null &"' % (filename) 
    os.system(command) 

を。 唯一のキャッチは、実行しているプロセスと同様にbashインスタンスをロードし、若干のオーバーヘッドを提供することです。

関連する問題