In python (on a Linux system), I'm launching a command using os.system()
and retrieving the return code. If that return code is different from 0, I would like to make the program exit with that same return code. So I wrote:
ret = os.system(cmd)
if ret != 0:
print "exit with status %s" % ret
sys.exit(ret)
When the return code is lower than 256, it works fine, but when it's greater than 255, the exit code used is 0. How can I make sys.exit() accept codes greater than 255?
Edit: the limit is actually 255
In fact, the ret
variable receives 256, but sys.exit()
fails to use it, so the program returns 0 instead. When I launch cmd
manually, I see that it returns 1, not 256.
Works for me (CentOS 5.5, Python 2.6.5):
$ python
>>> import sys
>>> sys.exit(245)
$ echo $?
245
Actually, the documentation indicates that
exit status indication: a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status (if the signal number is zero); the high bit of the low byte is set if a core file was produced.
So I need to process the number returned by sys.exit() in order to retrieve the real exit status, like so:
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)
And now it works: ret contains 1 instead of 256.
You can't shouldn't, because the system reserves exit codes above 128 for itself. If the return code is from 0 to 127, it means that the program exited by itself. If the return code is higher than 128, it means that the program was terminated by a system signal (e.g. SIGKILL or SIGTERM). The signal number is the result code minus 128.
You'll need to detect it and make some other kind of output indication, I think. Perhaps print the return code to STDOUT and then return with either 0 (normal exit, normal output) or 1 (cmd had a non-zero return value, output means something).
edit: Apparently (from this comment), Python is more clever than a shell script... To put it back into a regular Linux exit code, try this:
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
Although this ignores the core-dump information.