如何绕过 python 中 sys.exit() 的 0-255 范围限制?

Posted

技术标签:

【中文标题】如何绕过 python 中 sys.exit() 的 0-255 范围限制?【英文标题】:How to bypass the 0-255 range limit for sys.exit() in python? 【发布时间】:2010-12-15 09:16:29 【问题描述】:

在 python(在 Linux 系统上)中,我使用 os.system() 启动命令并检索返回码。如果该返回码与 0 不同,我想让程序以相同的返回码退出。于是我写了:

ret = os.system(cmd)
if ret != 0:
   print "exit with status %s" % ret
   sys.exit(ret)

返回码小于256时正常,大于255时退出码为0。如何让sys.exit()接受大于255的码?

编辑:限制实际上是 255

其实ret变量接收到256,但是sys.exit()使用失败,所以程序返回0代替。当我手动启动 cmd 时,我看到它返回 1,而不是 256。

【问题讨论】:

【参考方案1】:

其实documentation表示

退出状态指示:一个16位的数字,低字节是杀死进程的信号号,高字节是退出状态(如果信号号为零);如果生成了核心文件,则设置低字节的高位。

所以我需要处理 sys.exit() 返回的数字以检索真正的退出状态,如下所示:

ret = os.system(cmd)
# Ignore the first byte, use the second one only
ret = ret >> 8
if ret != 0:
   print "exit with status %s" % ret
   sys.exit(ret)

现在它起作用了:ret 包含 1 而不是 256。

【讨论】:

哦。我刚开始想知道为什么它在段错误终止时返回 0x8b00。 我认为,如果它转储核心,它会给你一个不同的退出代码,如果你从命令行运行它会得到什么。 你可以用subprocess.call代替os.system:比较python -c 'import os; print [os.system(["./exit-with", str(i)]) for i in [127,128,255,256,257]]'python -c 'import subprocess print [subprocess.call(["./exit-with", str(i)]) for i in [127,128,255,256,257]]',其中exit-with是ideone.com/zFelC【参考方案2】:

不能不应该,因为系统会为自己保留高于 128 的退出代码。如果返回码为 0 到 127,则表示程序自行退出。如果返回码高于 128,则意味着程序被系统信号(例如 SIGKILL 或 SIGTERM)终止。信号编号为结果码减 128。

我认为,您需要检测它并进行其他类型的输出指示。也许将返回码打印到 STDOUT,然后返回 0(正常退出,正常输出)或 1(cmd 有一个非零返回值,输出意味着什么)。

编辑:显然(来自this comment),Python 比 shell 脚本更聪明...要将其放回常规 Linux 退出代码,试试这个:

subprocess_exit_code = (ret >> 8) & 0x7f
subprocess_signal_number = ret & 0xff

if subpprocess_signal_number == 0:
  exit_code = subprocess_exit_code
else:
  exit_code = 128 + subprocess_signal_number

虽然这忽略了核心转储信息。

【讨论】:

【参考方案3】:

为我工作(CentOS 5.5,Python 2.6.5):

$ python
>>> import sys
>>> sys.exit(245)
$ echo $?
245

【讨论】:

对不起,我的错,限制是 255,而不是 127。 255 限制由 shell 强制执行:tldp.org/LDP/abs/html/exit-status.html 和 tldp.org/LDP/abs/html/exitcodes.html

以上是关于如何绕过 python 中 sys.exit() 的 0-255 范围限制?的主要内容,如果未能解决你的问题,请参考以下文章

python 如何中断程序停止程序退出程序?sys.exit()os._exit()os.kill()

如何读取 sys.exit() 返回的值并将其存储在变量中

Python中exit()和sys.exit()的区别

python中 os._exit() 和 sys.exit(), exit和exit 的用法和区别

python中 os._exit() 和 sys.exit(), exit和exit 的用法和区别

python中使用sys模块中sys.exit()好像不能退出?