I need to execute echo $?
using python3 and capture the exit status. I need this especially for capturing the Segmentation fault (core dumped)
status.
I tried :
>>> os.system('echo $?')
0
0
got 0 0
. Also, for segfault,
>>> os.system('./a.out')
Segmentation fault (core dumped)
35584
After above command, I again got:
>>> os.system('echo $?')
0
0
Also, why is 0
getting printed twice?
I went through the doccumentation of python-3 which says:
os.system(command)
On Unix, the return value is the exit status of the process encoded in the format specified for wait(). Note that POSIX does not specify the meaning of the return value of the C system() function, so the return value of the Python function is system-dependent.
Does this something say about such behavior? Help me clarify on this.
Note: I already ran the ulimit -c unlimited
before all above steps. The expected result should be non-zero or 139(to be specific).
Edit: I am thinking if there is a limitation on this!
Thanks!
No, you don't need to execute echo $?
. It wouldn't be useful. The exit status of the program is the return value of the function os.system
. That's what the number 35584
is. The documentation os os.system
tells you to read the documentation of os.wait
which explains
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.
However, note that depending on the shell, with os.system('./a.out')
, you may be getting the exit status of a.out
or the exit status of the shell itself. Normally there's no difference, because the exit status of the shell is the exit status of the last command it executes. But if the command dies from a signal, then there is a difference. The shell won't kill itself with the same signal, it will return a status that encodes the signal. In most shells, that's 128 + signal_number
. For example, if the program dies of signal 11 (segfault on Linux) and leaves a core dump, then its status as returned by wait
is 11. But if there's a shell in between, then the shell will exit normally with the exit code 128+11. That's what you're seeing: 35584 is (128 + 11) << 8
.
To avoid this complication, use subprocess.call
or one of its variants (you can use subprocess.run
if you don't need your code to run Python <=3.4).
returncode = subprocess.call(['./a.out'], shell=False).returncode
if returncode & 0xff == 0:
exit_code = returncode >> 8
print('The program exited normally with status {}.'.format(exit_code))
else:
print('The program was killed by signal {}.'.format(returncode))
If you run os.system('echo $?')
, this starts a new shell. You're printing the initial value of $?
in that shell, before it has run any command, and the initial value of $?
in a shell is 0.
You see 0
twice in the interactive environment because the first one is the one printed by the echo
command and the second one is the value of the Python expression. Compare os.system('echo hello')
.
Note that with os.system
, you can't access the output of the command, so if you print something with echo
, you can't use it in the program. You'd have to use functions in the subprocess
module for that, but you need this only if you need the output of ./a.out
, not to get its exit status.
When running:
>>> os.system('echo $?')
0
0
and if your previous command was successful a first 0
will be print by echo $?
and another one will be the return code of the call to echo $?
that has just succeeded so you will have another 0
printed.
The return code of the script/command that you execute will directly be returned to your python program by os.system function so you do not need to use echo $?
Examples:
$ more return_code*
::::::::::::::
return_code1.py
::::::::::::::
import os
print os.system('sleep 1')
#will print 0 after 1sec
::::::::::::::
return_code2.py
::::::::::::::
import os
print os.system('ls abcdef')
#will print a rc!=0 if the file abcdef is not present in your working directory
Executions:
$ python return_code1.py
0
and
$ python return_code2.py
ls: cannot access 'abcdef': No such file or directory
512
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With