2009-10-08 4 views
5

Dans un related question, j'ai demandé où trouver la documentation pour la fonction C "wait". C'était une tentative de comprendre les codes de retour pour le module commands.getstatusoutput(). Stackoverflow est passé, mais la documentation n'a pas aidé. Voici ce qui me déconcerte:Comment interpréter le code d'état dans 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) 

Lorsqu'il est exécuté sur OS X (Leopard) j'obtenir la sortie suivante: (. Ce qui correspond à la documentation)

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

Sur OS X, en faisant un « ls/fail echo $? " obtient la sortie suivante:

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

Lorsqu'il est exécuté sur Linux (Ubuntu Hardy) que je reçois la sortie suivante:

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

sur Ubuntu, faire "ls/échec" obtient 2:

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

Alors Python semble multiplier les codes de statut par 256. Hein? Est-ce documenté quelque part?

+0

la [réponse par @Schof] (http://stackoverflow.com/a/1535675/52074) répond à la question « lors de l'utilisation' commands.getstatusoutput() 'Pourquoi les exitcodes sont-ils multipliés par 256?" directement et avec un exemple de code. Les deux autres réponses disent plus ou moins "use" subprocess "au lieu de" commands.getstatusoutput() "" ou "voici comment utiliser subprocess". –

Répondre

10

Il y a un ensemble de fonctions dans le module os (os.WIFCONTINUED, os.WIFSTOPPED, os.WTERMSIG, os.WCOREDUMP, os.WIFEXITED, os.WEXITSTATUS, os.WIFSIGNALED, os.WSTOPSIG), qui correspondent aux macros de wait(2) manuel. Vous devriez les utiliser pour interpréter le code d'état.

Par exemple, pour obtenir le code de sortie, vous devez utiliser os.WEXITSTATUS(status)

Une meilleure idée serait de passer au module subprocess.

4

Wow. L'idée qu'il se multipliait par 256 m'a permis d'y être. La recherche de "commandes python +256" m'a amené à un article Python Module Of The Week qui explique ce qui se passe.

Voici un extrait de cette page:

La fonction getstatusoutput() exécute une commande via le shell et renvoie le code de sortie et la sortie de texte (stdout et stderr combinés). Les codes de sortie sont les mêmes que pour la fonction C wait() ou os.wait(). Le code est un numéro 16 bits de . L'octet faible contient le numéro de signal qui a tué le processus . Lorsque le signal est zéro, l'octet est l'état de sortie du programme . Si un fichier core a été produit, , le bit haut de l'octet bas est défini.

Et quelques-uns du code de 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

le retour de os.system (cmd) semble fonctionner de la même façon "aperçu qu'il multipliait par 256" – CaffeineAddiction

3

Regarder 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 

On voit sts tient la valeur de os.popen(...).close(). En regardant that documentation, os.popen(...).close() renvoie la valeur de os.wait:

os.wait()

attendre l'achèvement d'un processus enfant, et retourner un tuple contenant son pid et l'état de sortie indicatif: un nombre de 16 bits, dont le bas octet est le numéro de signal qui a tué le processus, et dont l'octet haut est l'état de sortie (si le numéro de signal est zéro); le bit haut de l'octet bas est défini si un fichier core a été produit. Disponibilité: Unix.

L'accent était le mien. Je suis d'accord sur le fait que cet "encodage" n'est pas très intuitif, mais au moins il était assez évident en un coup d'oeil qu'il était multiplié/décimal.

+0

Merci pour l'emphase, j'étais assez confus par ce que je voyais jusqu'à ce que je lise ceci .. –

0

Je pense que la détection de code est incorrecte.

"Si un fichier core a été produit, le bit haut de l'octet bas est défini." 128. signifie

donc je pense que la ligne de base devrait être

print 'Core? : %s' % bool(status & 128) 
Questions connexes