Je veux capturer le flux stdout
d'une commande Shell dans un script python (3), et pouvoir, en même temps, vérifier le code retour du Shell si elle renvoie une erreur (c'est-à-dire si son code de retour n'est pas 0).
subprocess.check_output
semble être la méthode appropriée pour ce faire. Depuis la page de manuel de subprocess
:
check_output(*popenargs, **kwargs)
Run command with arguments and return its output as a byte string.
If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
Pourtant, je n'arrive pas à obtenir le code retour de la commande Shell en cas d'échec. Mon code ressemble à ceci:
import subprocess
failing_command=['ls', 'non_existent_dir']
try:
subprocess.check_output(failing_command)
except:
ret = subprocess.CalledProcessError.returncode # <- this seems to be wrong
if ret in (1, 2):
print("the command failed")
Elif ret in (3, 4, 5):
print("the command failed very much")
Ce code lève une exception dans la gestion de l'exception elle-même:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
AttributeError: type object 'CalledProcessError' has no attribute 'returncode'
J'avoue que je ne sais pas où je me trompe.
Pour obtenir à la fois la sortie du processus et le code renvoyé:
from subprocess import Popen, PIPE
p = Popen(["ls", "non existent"], stdout=PIPE)
output = p.communicate()[0]
print(p.returncode)
subprocess.CalledProcessError
est une classe. Pour accéder à returncode
utilisez l'instance d'exception:
from subprocess import CalledProcessError, check_output
try:
output = check_output(["ls", "non existent"])
returncode = 0
except CalledProcessError as e:
output = e.output
returncode = e.returncode
print(returncode)
Très probablement ma réponse n'est plus pertinente, mais je pense qu'elle peut être résolue avec ce code:
import subprocess
failing_command='ls non_existent_dir'
try:
subprocess.check_output(failing_command, Shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
ret = e.returncode
if ret in (1, 2):
print("the command failed")
Elif ret in (3, 4, 5):
print("the command failed very much")