rypel
rypel

Reputation: 4864

How to hide output of subprocess

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?


See Python os.system without the output for approaches specific to os.system - although modern code should normally use the subprocess library instead.

Upvotes: 382

Views: 370527

Answers (5)

Zags
Zags

Reputation: 41210

Use subprocess.check_output (new in python 2.7). It will captures stdout as the return value of the function, which both prevents it from being sent to standard out and makes it availalbe for you to use programmatically. Like subprocess.check_call, this raises an exception if the command fails, which is generally what you want from a control-flow perspective. Example:

import subprocess
try:
    output = subprocess.check_output(['espeak', text])
except subprocess.CalledProcessError:
    # Handle failed call

You can also suppress stderr with:

    output = 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:
        output = subprocess._check_call(['espeak', text], stdout=FNULL)
    except subprocess.CalledProcessError:
        # Handle failed call

Here, you can suppress stderr with

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

Upvotes: 37

jdi
jdi

Reputation: 92569

For python >= 3.3, Redirect the output to DEVNULL:

import os
import subprocess

retcode = subprocess.call(['echo', 'foo'], 
    stdout=subprocess.DEVNULL,
    stderr=subprocess.STDOUT)

For python <3.3, including 2.7 use:

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")

Upvotes: 609

Josh Correia
Josh Correia

Reputation: 4346

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)

Upvotes: 34

lolamontes69
lolamontes69

Reputation: 39

Why not use commands.getoutput() instead?

import commands

text = "Mario Balotelli" 
output = 'espeak "%s"' % text
print text
a = commands.getoutput(output)

Upvotes: -7

jfs
jfs

Reputation: 414215

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

Upvotes: 106

Related Questions