如何绕过Python中sys.exit()的0-255范围限制?
在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