【问题标题】:How to interpret status code in Python commands.getstatusoutput()如何在 Python commands.getstatusoutput() 中解释状态码
【发布时间】:2010-12-04 20:58:55
【问题描述】:

related question 中,我询问在哪里可以找到 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。嗯?这是否记录在某处?

【问题讨论】:

  • answer by @Schof 回答了“使用 commands.getstatusoutput() 时为什么退出代码乘以 256?”这个问题。直接并带有示例代码。其他两个答案或多或少说“使用subprocess 而不是commands.getstatusoutput()”或“这是如何使用子进程”。

标签: python command subprocess exit-code


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    这是来自该页面的 sn-p:

    函数 getstatusoutput() 运行一个 通过 shell 命令并返回 退出代码和文本输出(stdout 和标准错误相结合)。退出代码 与 C 函数相同 等待()或 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')
    

    【讨论】:

    • os.system(cmd) 的返回似乎以同样的方式工作insight that it was multiplying by 256
    【解决方案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() 的值。查看that documentationos.popen(...).close()返回os.wait的值:

    os.wait()

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

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

    【讨论】:

    • 感谢您的强调,在我读到这篇文章之前,我对所看到的内容感到非常困惑..
    【解决方案4】:

    我认为代码检测不正确。

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

    所以我认为核心线应该是

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多