7

在一个相关问题中,我询问在哪里可以找到 C 函数“等待”的文档。这是试图找出 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

4 回答 4

11

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

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

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

于 2009-10-08T04:54:19.807 回答
4

哇。它乘以 256 的洞察力让我到了那里。搜索“python commands +256”让我看到了一篇Python Module Of The Week文章,它解释了发生了什么。

这是该页面的一个片段:

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

还有一些 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')
于 2009-10-08T04:44:39.707 回答
3

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

重点是我的。我同意这种“编码”并不是非常直观,但至少乍一看它被相乘/位移是相当明显的。

于 2009-10-08T04:51:46.223 回答
0

我认为代码检测不正确。

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

所以我认为核心线应该是

print 'Core? : %s' % bool(status & 128)
于 2009-11-04T17:04:50.213 回答