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

8 投票
3 回答
6713 浏览
提问于 2025-04-16 08:34

在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。

3 个回答

3

不能不应该这样做,因为系统会把128以上的退出代码留给自己使用。如果返回代码在0到127之间,说明程序是自己退出的。如果返回代码超过128,说明程序是被系统信号终止的(比如SIGKILL或SIGTERM)。信号编号就是返回代码减去128。

你需要检测这个情况,并做一些其他的输出提示。我觉得可以把返回代码打印到标准输出(STDOUT),然后返回0(正常退出,正常输出)或者1(命令有非零返回值,输出有意义)。

补充:显然(根据这个评论),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

不过这样做会忽略核心转储信息。

6

其实,文档上说明了

退出状态的表示:这是一个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。

-3

对我来说是有效的(CentOS 5.5,Python 2.6.5):

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

撰写回答