2013-03-09 10 views
19

Voglio catturare il flusso stdout di un comando shell in uno script python (3) ed essere in grado, allo stesso tempo, di controllare il codice di ritorno della shell comando se restituisce un errore (cioè se il suo codice di ritorno non è 0).Controllare il codice di ritorno di un comando quando il sottoprocesso solleva un'eccezione CalledProcessError

subprocess.check_output sembra essere il metodo appropriato per farlo. Dalla pagina man subprocess s':

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. 

Eppure, non riesco ad ottenere il codice di ritorno del comando di shell quando non riesce. Il mio codice è simile al seguente:

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

Questo codice solleva un'eccezione nella gestione della deroga stessa:

Traceback (most recent call last): 
    File "<stdin>", line 4, in <module> 
AttributeError: type object 'CalledProcessError' has no attribute 'returncode' 

Ammetto che non so dove ho sbagliato.

risposta

33

ottenere sia l'uscita di processo e il codice restituito:

from subprocess import Popen, PIPE 

p = Popen(["ls", "non existent"], stdout=PIPE) 
output = p.communicate()[0] 
print(p.returncode) 

subprocess.CalledProcessError è una classe. Per accedere returncode utilizzare l'istanza eccezione:

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) 
+0

ringrazio molto, funziona come un fascino :) – michaelmeyer

2

Molto probabilmente la mia risposta non è più rilevante, ma penso che potrebbe essere risolto con questo codice:

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