web-dev-qa-db-ja.com

Python実行可能ファイルへの呼び出しで出力を抑制する

呼び出されたときに出力を生成するAという名前のバイナリがあります。 Bashシェルから呼び出すと、ほとんどの出力は_A > /dev/null_によって抑制されます。すべての出力は_A &> /dev/null_によって抑制されます

Bを呼び出す必要があるAという名前のpythonスクリプトがあります。 Bからのすべての出力を抑制しながら、Aからの出力を生成できるようにしたいと思います。

Bの中から、os.system('A')os.system('A > /dev/null')、およびos.system('A &> /dev/null')os.execvp('...')などを試しましたが、どれもしませんでしたそれらのうち、Aからのすべての出力を抑制します。

_B &> /dev/null_を実行できましたが、それはBのすべての出力も抑制し、それは望ましくありません。

誰にも提案がありますか?

44
Lin

Python 2.4の場合、 サブプロセスモジュール :を使用できます。

>>> import subprocess
>>> s = subprocess.Popen(['cowsay', 'hello'], \
      stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
>>> print s
 _______ 
< hello >
 ------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
57
Manuel
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も指定する必要があります。ただし、文字列の内容が慎重に検証されていない場合、セキュリティ上の危険があるため、これは避ける必要があります。

102
DNS

検索エンジンがこの古い質問(私のように)につながる場合、PIPEを使用すると deadlocks になる可能性があることに注意してください。実際、パイプはバッファリングされるため、だれも読み取らなくても、パイプに一定のバイト数を書き込むことができます。ただし、バッファのサイズは有限です。その結果、プログラムAの出力がバッファよりも大きい場合、Aは書き込み時にブロックされ、呼び出し側プログラムBはAの終了を待ちます。しかし、この特定のケースでは...以下。

それでも、Devin JeanpierreとDNSのソリューションを使用することをお勧めします。

12
Po' Lazarus

Os.system()のドキュメントで言及されているように、 subprocess モジュールを使用し、必要に応じて、stdout = open(os.devnull、 'w')(およびおそらくstderrでも同じ)を設定サブプロセスを開きます。

8

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

tgt_file = "./bogus.txt"
os.sytem("d2u '%s' &> /dev/null" % tgt_file)

これは、subprocess.STDOUTを処理したくない場合に機能するようです。

1
Rob Carr

私が使う:

call(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

ここで、commandはコマンドの文字列+引数です

これが機能するには、サブプロセスをインポートする必要があります

0
TTT

STDOUTのみをキャプチャする必要がある場合、変数に割り当てないのですか?例えば:

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(string)を呼び出すたびに、書き込まれたバイト数が吐き出されていました。それをvairableに割り当てると、その出力は抑制されます。

0
ECJB

バックアップタスクの開始など、コマンドの完了を待たない場合は、bashを介してコマンドを渡すことで、リダイレクトを正常に動作させることができます。

たとえば、aplayを使用してサウンドファイルを開始する場合:

import os

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

この方法で、新しいプロセスを生成し、終了するのを待たずに、端末への印刷を停止できます。唯一の問題は、実行中のプロセスと同様にbashインスタンスをロードすることで、わずかなオーバーヘッドが発生します。

0
PiBorg