2009-10-08 6 views
5

In un related question, ho chiesto dove trovare la documentazione per la funzione C "attendere". Questo è stato un tentativo di capire i codici di ritorno per il modulo commands.getstatusoutput(). Stackoverflow è arrivato, ma la documentazione non ha aiutato. Ecco cosa mi lascia perplesso:Come interpretare il codice di stato in python commands.getstatusoutput()

#!/usr/bin/python 
import commands 
goodcommand = 'ls /' 
badcommand = 'ls /fail' 
status, output = commands.getstatusoutput(goodcommand) 
print('Good command reported status of %s' % status) 
status, output = commands.getstatusoutput(badcommand) 
print('Bad command reported status of %s' % status) 

Quando eseguito su OS X (Leopard) ottengo il seguente output: (. Il che corrisponde alla documentazione)

$ python waitest.py 
Good command reported status of 0 
Bad command reported status of 256 

Su OS X, facendo un "ls/fallisco ; echo $? " ottiene il seguente risultato:

$ ls /fail ; echo $? 
ls: /fail: No such file or directory 
1 

Quando viene eseguito su Linux (Ubuntu Hardy) ottengo il seguente output:

$ python waitest.py 
Good command reported status of 0 
Bad command reported status of 512 

Su Ubuntu, fare "ls/fail" ottiene un 2:

$ ls /fail ; echo $? 
ls: cannot access /fail: No such file or directory 
2 

Quindi Python sembra moltiplicare i codici di stato per 256. Eh? Questo è documentato da qualche parte?

+0

la [risposta da @Schof] (http://stackoverflow.com/a/1535675/52074) risponde alla domanda "quando si usa' commands.getstatusoutput() 'perché i codici di uscita sono moltiplicati per 256?" direttamente e con codice di esempio. Le altre due risposte più o meno dicono "usa" sottoprocesso "invece di' commands.getstatusoutput() '" o "ecco come usare il sottoprocesso". –

risposta

10

v'è un insieme di funzioni in os modulo (os.WIFCONTINUED, os.WIFSTOPPED, os.WTERMSIG, os.WCOREDUMP, os.WIFEXITED, os.WEXITSTATUS, os.WIFSIGNALED, os.WSTOPSIG), che corrispondono a macro da wait(2) manuale. Dovresti usarli per interpretare il codice di stato.

Ad esempio, per ottenere il codice di uscita è necessario utilizzare os.WEXITSTATUS(status)

Un'idea migliore sarebbe quella di passare a modulo subprocess.

4

Wow. L'intuizione che stava moltiplicando per 256 mi ha portato lì. La ricerca di "comandi python +256" mi ha portato a un articolo Python Module Of The Week che spiega cosa sta succedendo.

Ecco un frammento da quella pagina:

La funzione getstatusoutput() esegue un comando tramite la shell e restituisce il codice uscita e l'uscita di testo (stdout e stderr combinato). I codici di uscita sono gli stessi della funzione C wait() o os.wait(). Il codice è un numero a 16 bit . Il byte basso contiene il numero del segnale che ha ucciso il processo . Quando il segnale è zero, il byte alto è lo stato di uscita del programma . Se è stato prodotto un file core, viene impostato il bit più alto del byte basso.

E alcuni di codice di Doug:

from commands import * 

def run_command(cmd): 
    print 'Running: "%s"' % cmd 
    status, text = getstatusoutput(cmd) 
    exit_code = status >> 8 
    signal_num = status % 256 
    print 'Signal: %d' % signal_num 
    print 'Exit : %d' % exit_code 
    print 'Core? : %s' % bool(exit_code/256) 
    print 'Output:' 
    print text 
    print 

run_command('ls -l *.py') 
run_command('ls -l *.notthere') 
run_command('echo "WAITING TO BE KILLED"; read input') 
+0

il ritorno di os.system (cmd) sembra funzionare allo stesso modo 'intuizione che si stava moltiplicando per 256' – CaffeineAddiction

3

Guardando commands.py:

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell.""" 
    import os 
    pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') 
    text = pipe.read() 
    sts = pipe.close() 
    if sts is None: sts = 0 
    if text[-1:] == '\n': text = text[:-1] 
    return sts, text 

Vediamo sts contiene il valore di os.popen(...).close(). Guardando that documentation, os.popen(...).close() restituisce il valore di os.wait:

os.wait()

Attendere il completamento di un processo figlio, e restituisce una tupla contenente il suo identificativo e l'indicazione stato di uscita: un numero a 16 bit, il cui basso byte è il numero del segnale che ha ucciso il processo e il cui byte alto è lo stato di uscita (se il numero del segnale è zero); il bit più alto del byte basso viene impostato se è stato prodotto un file core. Disponibilità: Unix.

L'enfasi era mia. Sono d'accordo che questa "codifica" non è terribilmente intuitiva, ma almeno era abbastanza ovvio a prima vista che si stava moltiplicando/spostando il bit.

+0

Grazie per l'enfasi, ero abbastanza confuso da quello che stavo vedendo fino a quando ho letto questo .. –

0

Penso che il rilevamento del codice sia errato.

"Se è stato prodotto un file core, viene impostato il bit più alto del byte basso." significa 128.

quindi penso che la linea di base dovrebbe essere

print 'Core? : %s' % bool(status & 128) 
Problemi correlati