2009-10-08 9 views
5

In einem related question fragte ich, wo die Dokumentation für die C-Funktion "wait" zu finden ist. Dies war ein Versuch, Rückgabecodes für das commands.getstatusoutput() Modul herauszufinden. Stackoverflow kam durch, aber die Dokumentation half nicht. Hier ist, was mir ein Rätsel:Wie interpretiere ich den Statuscode 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) 

Wenn auf OS X (Leopard) laufen bekomme ich folgende Ausgabe: (. Welche der Dokumentation übereinstimmt)

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

Unter OS X eine „ls/tun scheitern ; echo $? " die folgende Ausgabe erhält:

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

Wenn auf Linux (Ubuntu Hardy) betreibe ich folgende Ausgabe:

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

Unter Ubuntu tun "ls/fail" erhält einen 2:

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

Also Python scheint Statuscodes mit 256 zu multiplizieren. Huh? Ist das irgendwo dokumentiert?

+0

die [Antwort von @Schof] (http://stackoverflow.com/a/1535675/52074) beantwortet die Frage „sein sollte, wenn mit' commands.getstatusoutput() 'Warum werden die Exitcodes mit 256 multipliziert?" direkt und mit Beispielcode. Die anderen beiden Antworten sagen mehr oder weniger "subprocess verwenden" anstelle von "commands.getstatusoutput()' "oder" hier ist wie Subprozess zu verwenden ". –

Antwort

10

Es gibt eine Reihe von Funktionen in os Modul (os.WIFCONTINUED, os.WIFSTOPPED, os.WTERMSIG, os.WCOREDUMP, os.WIFEXITED, os.WEXITSTATUS, os.WIFSIGNALED, os.WSTOPSIG), die Makros aus wait(2) manuellen entsprechen. Sie sollten sie verwenden, um den Statuscode zu interpretieren.

Zum Beispiel den Exit-Code bekommen Sie os.WEXITSTATUS(status)

Eine bessere Idee zu subprocess Modul wäre umschalten sollte.

4

Wow. Die Einsicht, dass es sich mit 256 multiplizierte, brachte mich dahin. Die Suche nach "Python-Befehlen +256" brachte mich zu einem Python Module Of The Week Artikel, der erklärt, was vor sich geht.

Hier ist ein Ausschnitt aus dieser Seite:

Die Funktion getstatusoutput() führt einen Befehl über die Schale und gibt den Beendigungscode und die Textausgabe (stdout und Stderr kombiniert). Die Exit-Codes sind die gleichen wie für die C-Funktion wait() oder os.wait(). Der Code ist eine 16-Bit-Nummer. Das Low-Byte enthält die Signalnummer, die den Prozess beendete. Wenn das Signal Null ist, ist das High-Byte der Exit-Status des Programms . Wenn eine Kerndatei erzeugt wurde, wird das High-Bit des Low-Bytes gesetzt.

Und einige von Dougs Code:

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

die Rückkehr von os.system (cmd) scheint auf die gleiche Weise zu funktionieren "Einsicht, dass es mit 256 multiplizierte" – CaffeineAddiction

3

bei commands.py Suche:

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 

Wir sehen sts den Wert os.popen(...).close() hält. Mit Blick auf that documentation, os.popen(...).close() gibt den Wert os.wait:

os.wait()

Warten auf Beendigung eines Kindprozesses und kehrt ein Tupel seine PID- und Ausgangsstatusanzeige enthält: eine 16-Bit-Zahl, deren niedrigen Byte ist die Signalnummer, die den Prozess beendet hat, und , deren High-Byte der Exit-Status ist (wenn die Signalnummer Null ist); Das High-Bit des Low-Bytes wird gesetzt, wenn eine Core-Datei erzeugt wurde. Verfügbarkeit: Unix.

Der Schwerpunkt lag bei mir. Ich stimme zu, dass dieses "Encoding" nicht besonders intuitiv ist, aber es war zumindest auf den ersten Blick ziemlich offensichtlich, dass es multipliziert/bitverschoben wurde.

+0

Vielen Dank für die Betonung, ich war ziemlich verwirrt von dem, was ich sah, bis ich dies las .. –

0

Ich denke, dass die Codeerkennung falsch ist.

"Wenn eine Core-Datei erstellt wurde, wird das High-Bit des Low-Bytes gesetzt." bedeutet 128

so denke ich, die Kernleitung

print 'Core? : %s' % bool(status & 128) 
Verwandte Themen