如何解释 Python commands.getstatusoutput() 中的状态代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1535672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:31:26  来源:igfitidea点击:

How to interpret status code in Python commands.getstatusoutput()

pythoncommandsubprocessexit-code

提问by Schof

In a related question, I asked where to find the documentation for the C function "wait." This was an attempt to figure out return codes for the commands.getstatusoutput() module. Stackoverflow came through, but the documentation didn't help. Here's what puzzles me:

在一个相关的问题中,我问到哪里可以找到 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)

When run on OS X (Leopard) I get the following output: (Which matches the documentation.)

在 OS X (Leopard) 上运行时,我得到以下输出:(与文档匹配。)

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

On OS X, doing an "ls /fail ; echo $?" gets the following output:

在 OS X 上,执行“ls /fail ; echo $?” 得到以下输出:

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

When run on Linux (Ubuntu Hardy) I get the following output:

在 Linux (Ubuntu Hardy) 上运行时,我得到以下输出:

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

On Ubuntu, doing "ls /fail" gets a 2:

在 Ubuntu 上,执行 "ls /fail" 会得到 2:

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

So Python appears to be multiplying status codes by 256. Huh? Is this documented somewhere?

所以 Python 似乎是将状态代码乘以 256。嗯?这是在某处记录的吗?

回答by abbot

There is a set of functions in osmodule (os.WIFCONTINUED, os.WIFSTOPPED, os.WTERMSIG, os.WCOREDUMP, os.WIFEXITED, os.WEXITSTATUS, os.WIFSIGNALED, os.WSTOPSIG), which correspond to macros from wait(2)manual. You should use them to interpret the status code.

os模块 ( os.WIFCONTINUED, os.WIFSTOPPED, os.WTERMSIG, os.WCOREDUMP, os.WIFEXITED, os.WEXITSTATUS, os.WIFSIGNALED, os.WSTOPSIG) 中有一组函数,它们对应于wait(2)手册中的宏。您应该使用它们来解释状态代码。

For example, to get the exit code you should use os.WEXITSTATUS(status)

例如,要获取您应该使用的退出代码 os.WEXITSTATUS(status)

A better idea would be to switch to subprocessmodule.

一个更好的主意是切换到subprocess模块。

回答by Schof

Wow. The insight that it was multiplying by 256 got me there. Searching for "python commands +256" got me to a Python Module Of The Weekarticle which explains what's going on.

哇。它乘以 256 的洞察力让我到达了那里。搜索“python 命令 +256”让我看到了一篇Python Module Of The Week文章,它解释了正在发生的事情。

Here's a snippet from that page:

这是该页面的一个片段:

The function getstatusoutput() runs a command via the shell and returns the exit code and the text output (stdout and stderr combined). The exit codes are the same as for the C function wait() or os.wait(). The code is a 16-bit number. The low byte contains the signal number that killed the process. When the signal is zero, the high byte is the exit status of the program. If a core file was produced, the high bit of the low byte is set.

函数 getstatusoutput() 通过 shell 运行命令并返回退出代码和文本输出(stdout 和 stderr 组合)。退出代码与 C 函数 wait() 或 os.wait() 相同。该代码是一个 16 位数字。低字节包含杀死进程的信号编号。当信号为零时,高字节为程序退出状态。如果生成了核心文件,则设置低字节的高位。

And some of Doug's 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')

回答by Mark Rushakoff

Looking at commands.py:

看着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

We see stsholds the value of os.popen(...).close(). Looking at thatdocumentation, os.popen(...).close()returns the value of os.wait:

我们看到sts持有 的价值os.popen(...).close()。查看文档os.popen(...).close()返回以下值os.wait

os.wait()

Wait for completion of a child process, and return a tuple containing its pid and exit status indication: a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status(if the signal number is zero); the high bit of the low byte is set if a core file was produced. Availability: Unix.

os.wait()

等待子进程完成,并返回一个包含其pid和退出状态指示的元组:一个16位的数字,低字节是杀死进程的信号号,高字节是退出状态(如果信号数字为零);如果生成了核心文件,则设置低字节的高位。可用性:Unix。

Emphasis was mine. I agree that this "encoding" isn't terribly intuitive, but at least it was fairly obvious at a glance that it was being multiplied/bit-shifted.

重点是我的。我同意这种“编码”不是非常直观,但至少它被乘法/位移一目了然。

回答by Felix Labrecque

I think the code detection is incorrect.

我认为代码检测不正确。

"If a core file was produced, the high bit of the low byte is set." means 128.

“如果生成了核心文件,则设置低字节的高位。” 表示 128。

so I think the core line should be

所以我认为核心线应该是

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