Come interpretare il codice di stato in Python comments.getstatusoutput()
-
20-09-2019 - |
Domanda
In un domanda correlata, Ho chiesto dove trovare la documentazione per la funzione C "Aspetta". Questo è stato un tentativo di capire i codici di ritorno per il modulo Commands.getStatusOutput ().Stackoverflow è arrivato, ma la documentazione non è stata d'aiuto.Ecco cosa mi lascia perplesso:
#!/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 eseguo su OS X (Leopard) ottengo il seguente output:(Che corrisponde alla documentazione.)
$ python waitest.py
Good command reported status of 0
Bad command reported status of 256
Su OS X, eseguendo un comando "ls /fail ;echo $?" ottiene il seguente output:
$ ls /fail ; echo $?
ls: /fail: No such file or directory
1
Quando eseguo 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, facendo "ls /fail" si ottiene un 2:
$ ls /fail ; echo $?
ls: cannot access /fail: No such file or directory
2
Quindi sembra che Python stia moltiplicando i codici di stato per 256.Eh?Questo è documentato da qualche parte?
Soluzione
V'è un insieme di funzioni in modulo os
(os.WIFCONTINUED
, os.WIFSTOPPED
, os.WTERMSIG
, os.WCOREDUMP
, os.WIFEXITED
, os.WEXITSTATUS
, os.WIFSIGNALED
, os.WSTOPSIG
), che corrispondono a macro da wait (2) manuale. Si dovrebbe usare loro di interpretare il codice di stato.
Ad esempio, per ottenere il codice di uscita è necessario utilizzare os.WEXITSTATUS(status)
Una migliore idea sarebbe quella di passare a modulo subprocess
.
Altri suggerimenti
Wow. L'intuizione che è stato moltiplicando per 256 mi ha fatto lì. Ricerca di "comandi python +256" mi ha fatto ad un Python Modulo della settimana articolo che spiega quello che sta succedendo.
Ecco un frammento da quella pagina:
La getstatusoutput function () gestisce un comando attraverso la shell e restituisce il codice di uscita e l'output di testo (stdout e stderr combinato). I codici di uscita sono gli stessi per la 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 processi. Quando il segnale è zero, la byte alto è lo stato di uscita del programma. Se un componente del sistema è stato prodotto, il bit del byte basso è impostato.
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')
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
detiene il valore di os.popen(...).close()
.Guardando Quello documentazione, os.popen(...).close()
restituisce il valore di os.wait
:
os.wait()
Attendi il completamento di un processo figlio e restituisce una tupla contenente il suo pid e l'indicazione dello stato di uscita:un numero a 16 bit, il cui byte basso è il numero del segnale che ha interrotto il processo, e il cui byte alto è lo stato di uscita (se il numero del segnale è zero);il bit alto del byte basso viene impostato se è stato prodotto un file core.Disponibilità:Unix.
L'enfasi è stata mia.Sono d'accordo sul fatto che questa "codifica" non è particolarmente intuitiva, ma almeno era abbastanza ovvio a prima vista che veniva moltiplicata/spostata in bit.
Credo che il rilevamento codice non è corretto.
"Se un componente del sistema è stato prodotto, il bit alto del byte basso è impostato". mezzi 128.
e quindi penso che la linea di base deve essere
print 'Core? : %s' % bool(status & 128)