web-dev-qa-db-fra.com

Comment masquer la sortie du sous-processus dans Python 2.7

J'utilise eSpeak sur Ubuntu et j'ai un script Python 2.7 qui imprime et prononce un message:

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

eSpeak produit les sons souhaités, mais encombre le shell avec des erreurs (ALSA lib ..., pas de connexion de socket), donc je ne peux pas facilement lire ce qui a été imprimé auparavant. Le code de sortie est 0.

Malheureusement, il n’existe aucune option documentée pour désactiver sa verbosité. Je cherche donc un moyen de ne la rendre silencieuse que visuellement et de garder le Shell ouvert propre pour toute interaction ultérieure.

Comment puis-je faire ceci?

253
rypel

Rediriger la sortie vers DEVNULL:

import os
import subprocess

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

En réalité, cela revient à exécuter cette commande Shell:

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

Voici une version plus portable (juste pour le fun, ce n'est pas nécessaire dans votre cas):

#!/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
84
jfs

Utilisez subprocess.check_output (nouveauté dans python 2.7). Il supprimera stdout et déclenchera une exception si la commande échoue. (En réalité, il retourne le contenu de stdout, vous pouvez donc l'utiliser plus tard dans votre programme si vous le souhaitez.) Exemple:

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

Vous pouvez également supprimer stderr avec:

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

Pour les versions antérieures à 2.7, utilisez

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

Ici, vous pouvez supprimer stderr avec

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

Depuis Python3, vous n'avez plus besoin d'ouvrir devnull et pouvez appeler subprocess.DEVNULL .

Votre code serait mis à jour en tant que tel:

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

si vous utilisez le module de sous-processus dans Windows (non spécifique à cette question, mais correspond à title) avec python 2.7x et que SEULES les erreurs que vous souhaitez supprimer (spécifiques à cette question), vous pouvez faire quelque chose comme ça:

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

vous devriez être capable de tester en utilisant le code ci-dessus sur votre système, mais s'il se trouve que 127.0.0.2 existe dans votre table arp, vous pouvez simplement choisir une adresse IP qui ne possède pas de NIC associée.

0
codeasaurus