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?
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())'
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.