web-dev-qa-db-fra.com

Rediriger le sous-processus stderr vers stdout

Je veux rediriger la sortie stderr d'un sous-processus vers stdout. La constante STDOUT devrait faire ça, non?

Cependant,

$ python >/dev/null -c 'import subprocess;\
                        subprocess.call(["ls", "/404"],stderr=subprocess.STDOUT)'

produit quelque chose. Pourquoi est-ce le cas et comment puis-je obtenir le message d'erreur sur stdout?

34
phihag

Une lecture attentive du code source donne la réponse. En particulier, le documentation est trompeur quand il dit:

subprocess.STDOUT
Valeur spéciale qui (...) indique que l'erreur standard doit aller dans la même poignée que la sortie standard.

Étant donné que stdout est défini sur "par défaut" (-1, techniquement) lorsque stderr=subprocess.STDOUT est évalué, stderr est également défini sur "par défaut". Malheureusement, cela signifie que la sortie stderr va toujours à stderr.

Pour résoudre le problème, passez le fichier stdout au lieu de subprocess.STDOUT:

$ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"],
                        stderr=sys.stdout.buffer)'

Ou, pour la compatibilité avec les versions 2.x héritées de Python:

$ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"],
                        stderr=sys.stdout.fileno())'
35
phihag

En fait, en utilisant subprocess.STDOUT fait exactement ce qui est indiqué dans la documentation: il redirige stderr vers stdout pour que par exemple.

proc = subprocess.Popen(self.task["command"], Shell=False, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ""
while (True):
    # Read line from stdout, break if EOF reached, append line to output
    line = proc.stdout.readline()
    line = line.decode()
    if (line == ""): break
    output += line

entraîne la variable output contenant la sortie du processus à la fois de stdout et de stderr.

stderr=subprocess.STDOUT redirige toutes les sorties de stderr directement vers stdout du processus appelant, ce qui est une différence majeure.

15
Maxxim