我需要使用python3执行echo $?
并捕获退出状态。我需要这个特别是为了捕获Segmentation fault (core dumped)
状态。
我试过了:
>>> os.system('echo $?')
0
0
得到0 0
。此外,对于段错误,
>>> os.system('./a.out')
Segmentation fault (core dumped)
35584
经过上述命令,我又得到了:
>>> os.system('echo $?')
0
0
另外,为什么0
会被打印两次?
我经历了python-3的说明,其中说:
使用os.system(命令)
在Unix上,返回值是以wait()指定的格式编码的进程的退出状态。请注意,POSIX没有指定C系统()函数的返回值的含义,因此Python函数的返回值是依赖于系统的。
这件事是否说明了这种行为? 请帮我澄清一下。
注意:我已经在上述所有步骤之前运行了ulimit -c unlimited
。预期结果应为非零或139(具体)。
编辑:我在想是否存在限制!
谢谢!
答案 0 :(得分:2)
不,您不需要执行echo $?
。它不会有用。程序的退出状态是函数os.system
的返回值。那是35584
的数字。 documentation os os.system
告诉您阅读解释
os.wait
一个16位数字,其低字节是杀死进程的信号编号,其高字节是退出状态(如果信号编号为零);如果生成了核心文件,则设置低字节的高位。
但是,请注意,根据shell,使用os.system('./a.out')
,您可能会获得a.out
的退出状态或shell本身的退出状态。通常情况没有区别,因为shell的退出状态是它执行的最后一个命令的退出状态。但如果命令死于信号,则存在差异。 shell不会使用相同的信号自杀,它将返回编码信号的状态。在大多数贝壳中,128 + signal_number
。例如,如果程序死于信号11(Linux上的段错误)并留下核心转储,那么wait
返回的状态为11.但是如果它们之间存在shell,那么shell将会通常使用退出代码128 + 11退出。这就是你所看到的:35584是(128 + 11) << 8
。
要避免这种复杂情况,请使用subprocess.call
或其中一种变体(如果您不需要代码来运行Python&lt; = 3.4),则可以使用subprocess.run
。
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))
如果您运行os.system('echo $?')
,则会启动一个新shell。您在运行任何命令之前在该shell中打印$?
的初始值,并且shell中$?
的初始值为0。
您在交互式环境中看到0
两次,因为第一个是echo
命令打印的,第二个是Python表达式的值。比较os.system('echo hello')
。
请注意,使用os.system
,您无法访问命令的输出,因此如果您使用echo
打印某些内容,则无法在程序中使用它。您必须使用subprocess
module中的功能,但只有在需要./a.out
的输出时才需要此功能,而不是为了获得退出状态。
答案 1 :(得分:1)
运行时:
>>> os.system('echo $?')
0
0
如果您之前的命令成功,则第一个0
将由echo $?
打印,另一个将是echo $?
调用的返回代码,该代码刚刚成功,因此您将打印另一个0
。
您执行的脚本/命令的返回代码将直接通过os.system函数返回到您的python程序,因此您不需要使用echo $?
<强>示例:强>
$ 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
<强>处决:强>
$ python return_code1.py
0
和
$ python return_code2.py
ls: cannot access 'abcdef': No such file or directory
512
答案 2 :(得分:0)
我为上述问题编写了以下代码,并按预期工作。我使用subprocess.Popen()
方法来满足自己的要求。我使用sample.returncode
来获取shell的退出状态。
def run_cmd():
ret = 0
sample_cmd = "./a.out"
sample = subprocess.Popen(sample_cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out_stdout, out_stderr = sample.communicate()
if sample.returncode != 0:
print ("OUTPUT: %s\nERROR: %s\n"%(out_stdout, out_stderr))
print ("Command: %s \nStatus: FAIL "%(sample_cmd))
sys.stdout.flush()
if sample.returncode == 139:
print('Segmentation fauilt(core dumped) occured...with status: ', sample.returncode)
ret = sample.returncode
else:
ret = 1
else:
print ("OUTPUT: %s\n"%(out_stdout))
print ("Command: %s \nStatus: PASS "%(sample_cmd))
ret = 0