2010-12-15 97 views
6

在Python(在Linux系统上)中,我使用os.system()启动命令并检索返回码。如果返回码不是0,我想用相同的返回码退出程序。所以我写了:如何绕过python中sys.exit()的0-255范围限制?

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,我

回答

0

作品(CentOS的5.5,Python的2.6.5):

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

这是不正确的,它不测试同样的事情。 – unwind 2010-12-15 09:27:54

+0

对不起,我的错误,限制是255,而不是127. – 2010-12-15 09:36:37

+2

255限制由shell执行:http://tldp.org/LDP/abs/html/exit-status.html和http:// tldp。 org/LDP/abs/html/exitcodes.html – 2010-12-15 09:38:38

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 

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

5

实际上,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) 

而现在它的工作原理:滞留包含1个,而不是256

+0

哦。我刚开始想知道为什么它会在segfaulty终止时返回0x8b00。 – ulidtko 2010-12-15 09:45:26

+0

我认为如果它转储核心,将给你一个不同的退出代码,如果你从命令行运行它,你会得到什么。 – 2010-12-15 09:53:01

+1

你可以使用'subprocess.call'而不是'os.system':compare'python -c'import os;打印[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]]''where'exit-with'是http://ideone.com/zFelC – jfs 2010-12-15 10:05:40