How to hide output of subprocess in Python 2.7

2018-12-31 04:33发布

I'm using eSpeak on Ubuntu and have a Python 2.7 script that prints and speaks a message:

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

eSpeak produces the desired sounds, but clutters the shell with some errors (ALSA lib..., no socket connect) so i cannot easily read what was printed earlier. Exit code is 0.

Unfortunately there is no documented option to turn off its verbosity, so I'm looking for a way to only visually silence it and keep the open shell clean for further interaction.

How can I do this?

6条回答
余生无你
2楼-- · 2018-12-31 04:37

if you happen to be using the subprocess module in windows (not specific to this question but matches title) with python 2.7x and it is ONLY the errors you want to suppress (specific to this question), you can do something like this:

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

you should be able to test using the code above on your system but if 127.0.0.2 happens to exist in your arp table you can just pick an ip that does not have a nic associated with it.

查看更多
时光乱了年华
3楼-- · 2018-12-31 04:42

Redirect the output to DEVNULL:

import os
import subprocess

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

It is effectively the same as running this shell command:

retcode = os.system("echo 'foo' &> /dev/null")
查看更多
孤独总比滥情好
4楼-- · 2018-12-31 04:43

As of Python3 you no longer need to open devnull and can call subprocess.DEVNULL.

Your code would be updated as such:

import subprocess
text = 'Hello World.'
print text
subprocess.call(['espeak', text], stderr=subprocess.DEVNULL)
查看更多
若你有天会懂
5楼-- · 2018-12-31 04:48

Here's a more portable version (just for fun, it is not necessary in your case):

#!/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
查看更多
闭嘴吧你
6楼-- · 2018-12-31 04:50

Use subprocess.check_output (new in python 2.7). It will suppress stdout and raise an exception if the command fails. (It actually returns the contents of stdout, so you can use that later in your program if you want.) Example:

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

You can also suppress stderr with:

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

For earlier than 2.7, use

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

Here, you can suppress stderr with

        subprocess._check_call(['espeak', text], stdout=FNULL, stderr=FNULL)
查看更多
与风俱净
7楼-- · 2018-12-31 04:50

Why not use commands.getoutput() instead?

import commands

text = "Mario Balotelli" 
output = 'espeak "%s"' % text
print text
a = commands.getoutput(output)
查看更多
登录 后发表回答