Как интерпретировать код состояния в Python commands.getstatusoutput () - PullRequest
7 голосов
/ 08 октября 2009

В связанном вопросе я спросил, где найти документацию для функции C "wait". Это была попытка выяснить коды возврата для модуля commands.getstatusoutput (). Прошел Stackoverflow, но документация не помогла. Вот что меня озадачивает:

#!/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)

При запуске на OS X (Leopard) я получаю следующий вывод: (что соответствует документации.)

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

В OS X выполните команду "ls / fail; echo $?" получает следующий вывод:

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

При запуске в Linux (Ubuntu Hardy) я получаю следующий вывод:

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

В Ubuntu выполнение команды "ls / fail" дает 2:

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

Значит, Python, похоже, умножает коды состояния на 256. А? Это где-то задокументировано?

Ответы [ 4 ]

11 голосов
/ 08 октября 2009

В модуле os имеется набор функций (os.WIFCONTINUED, os.WIFSTOPPED, os.WTERMSIG, os.WCOREDUMP, os.WIFEXITED, os.WEXITSTATUS, os.WIFSIGNALED, os.WSTOPSIG), соответствующих к макросам из инструкция wait (2) . Вы должны использовать их для интерпретации кода состояния.

Например, чтобы получить код выхода, вы должны использовать os.WEXITSTATUS(status)

Лучше было бы перейти на модуль subprocess.

4 голосов
/ 08 октября 2009

Ничего себе. Понимание, что это умножилось на 256, привело меня туда. Поиск "команд python +256" привел меня к статье Python Module of the Week , которая объясняет, что происходит.

Вот фрагмент этой страницы:

Функция getstatusoutput () выполняет Команда через оболочку и возвращает код выхода и вывод текста (стандартный вывод и stderr вместе взятые). Коды выхода такие же, как для функции C wait () или os.wait (). Код является 16-битное число. Младший байт содержит номер сигнала, который убил процесс. Когда сигнал равен нулю, старший байт - это статус выхода программа. Если файл ядра был создан, старший бит младшего байта установлен.

И часть кода Дуга:

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')
3 голосов
/ 08 октября 2009

Глядя на 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

Мы видим, sts содержит значение os.popen(...).close(). Глядя на , что документация , os.popen(...).close() возвращает значение os.wait:

os.wait()

Дождитесь завершения дочернего процесса и верните кортеж, содержащий его pid и индикацию состояния выхода: 16-битное число, младший байт которого является номером сигнала, который убил процесс, и , старший байт которого статус выхода (если номер сигнала равен нулю); старший бит младшего байта устанавливается, если был создан файл ядра. Наличие: Unix.

Акцент был мой. Я согласен, что это «кодирование» не очень интуитивно понятно, но, по крайней мере, с первого взгляда было очевидно, что его умножают / сдвигают в битах.

0 голосов
/ 04 ноября 2009

Я думаю, что обнаружение кода неверно.

"Если файл ядра был создан, устанавливается старший бит младшего байта." значит 128.

поэтому я думаю, что основная линия должна быть

print 'Core? : %s' % bool(status & 128)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...