web-dev-qa-db-ja.com

Python 2.7でサブプロセスの出力を隠す方法

私はUbuntuでeSpeakを使っていて、メッセージを印刷して話すPython 2.7スクリプトを持っています。

import subprocess
text = 'Hello World.'
print text
subprocess.call(['espeak', text])

eSpeakは望みの音を出しますが、いくつかのエラー(ALSA lib ...、ソケット接続なし)でシェルを乱雑にするので、私は以前に印刷されたものを容易に読むことができません。終了コードは0です。

残念ながら、その冗長性をオフにするための文書化されたオプションはありません。そのため、視覚的にそれを黙らせるだけで、さらなる対話のために開いているシェルをきれいに保つ方法を探しています。

これどうやってするの?

243
rypel

出力をDEV NULLにリダイレクトします。

import os
import subprocess

FNULL = open(os.devnull, 'w')
retcode = subprocess.call(['echo', 'foo'], stdout=FNULL, stderr=subprocess.STDOUT)

これは、このシェルコマンドを実行するのと実質的に同じです。

retcode = os.system("echo 'foo' &> /dev/null")
376
jdi

これはもっと移植性のあるバージョンです(ただの楽しみのために、それはあなたのケースで必要ではありません):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE, STDOUT

try:
    from subprocess import DEVNULL # py3k
except ImportError:
    import os
    DEVNULL = open(os.devnull, 'wb')

text = u"René Descartes"
p = Popen(['espeak', '-b', '1'], stdin=PIPE, stdout=DEVNULL, stderr=STDOUT)
p.communicate(text.encode('utf-8'))
assert p.returncode == 0 # use appropriate for your program error handling here
80
jfs

subprocess.check_output を使います(Python 2.7の新機能)。コマンドが失敗すると、標準出力を抑制し、例外を発生させます。 (実際にはstdoutの内容を返すので、必要に応じて後でプログラムで使用できます。)例:

import subprocess
try:
    subprocess.check_output(['espeak', text])
except subprocess.CalledProcessError:
    # Do something

Stderrを抑制することもできます。

    subprocess.check_output(["espeak", text], stderr=subprocess.STDOUT)

2.7より前のバージョンでは、

import os
import subprocess
with open(os.devnull, 'w')  as FNULL:
    try:
        subprocess._check_call(['espeak', text], stdout=FNULL)
    except subprocess.CalledProcessError:
        # Do something

ここで、stderrを抑制することができます。

        subprocess._check_call(['espeak', text], stdout=FNULL, stderr=FNULL)
27
Zags

Python 3では、devnullを開く必要がなくなり、 subprocess.DEVNULL を呼び出すことができます。

あなたのコードは以下のように更新されます。

import subprocess
text = 'Hello World.'
print(text)
subprocess.call(['espeak', text], stderr=subprocess.DEVNULL)
10
Josh Correia

あなたがたまたまウィンドウズのサブプロセスモジュール(この質問に特有ではないがタイトルにマッチする)をpython 2.7xと共に使用していて、それがあなたが抑制したいエラー(この質問に特有の)だけであるならば、あなたはこのようにすることができる

output = subprocess.check_output(["arp", "-a", "-N", "127.0.0.2"], stderr=subprocess.STDOUT)

あなたはあなたのシステム上で上記のコードを使ってテストすることができるはずですが127.0.0.2があなたのARPテーブルに存在するのなら、あなたはそれに関連するNICを持たないIPを選ぶことができます。

0
codeasaurus