Python 如何捕获子流程错误
在Python中,我运行使用FORTRAN生成的exe。我使用Python 如何捕获子流程错误,python,subprocess,Python,Subprocess,在Python中,我运行使用FORTRAN生成的exe。我使用子流程模块。exe访问和写入多个文件。如果我将这些文件设置为只读,我会在Python控制台中看到以下跟踪 我尝试使用try,除了语句。但我无法捕捉到错误。我还尝试使用p.stdout.readline()。但没有成功 有没有一种系统的方法来捕捉这种错误 代码: 回溯: forrtl: severe (9): permission to access file denied, unit 6, file C:\test\mar22_SSO
子流程
模块。exe访问和写入多个文件。如果我将这些文件设置为只读,我会在Python控制台中看到以下跟踪
我尝试使用try
,除了语句。但我无法捕捉到错误。我还尝试使用p.stdout.readline()
。但没有成功
有没有一种系统的方法来捕捉这种错误
代码:
回溯:
forrtl: severe (9): permission to access file denied, unit 6, file C:\test\mar22_SSOUT\RawReadLog.dat
Image PC Routine Line Source
test.exe 0116DC40 Unknown Unknown Unknown
test.exe 0113D42F Unknown Unknown Unknown
test.exe 0112AE97 Unknown Unknown Unknown
test.exe 0112A1DA Unknown Unknown Unknown
test.exe 0110D746 Unknown Unknown Unknown
test.exe 0108B9AC Unknown Unknown Unknown
test.exe 01173FE3 Unknown Unknown Unknown
test.exe 011588F5 Unknown Unknown Unknown
kernel32.dll 76D33677 Unknown Unknown Unknown
ntdll.dll 77A39F42 Unknown Unknown Unknown
ntdll.dll 77A39F15 Unknown Unknown Unknown
运行流程:
p = subprocess.Popen(['C:\\TGSSR\\test.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# shell = True is not needed
p = subprocess.run(['C:\\TGSSR\\test.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
要捕获错误消息,请执行以下操作:
stdout, stderr = p.communicate()
# stdout = normal output
# stderr = error output
stdout = p.stdout # stdout = normal output
stderr = p.stderr # stderr = error output
检查流程返回代码:
if p.returncode != 0:
# handle error
if p.returncode != 0:
# handle error
如果不需要Popen的所有功能,只需要获取标准输出,您还可以选择:
try:
output = subprocess.check_output('C:\\TGSSR\\test.exe')
except subprocess.CalledProcessError as e:
print("Oops... returncode: " + e.returncode + ", output:\n" + e.output)
else:
print("Everything ok:\n" + output)
编辑:正如mgilson在另一个答案中指出的那样,这需要一个非零的故障返回码。如果不是这样,您可以尝试以下方法:
output = subprocess.check_output('C:\\TGSSR\\test.exe')
if "permission to access file denied" in output:
print("Failed")
Python 3.5引入了一些字符串,这些字符串仅在出现错误时才会出现在标准输出上
以下是针对Python>=3.5更新的@kirbyfan64sos答案:
运行流程:
p = subprocess.Popen(['C:\\TGSSR\\test.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# shell = True is not needed
p = subprocess.run(['C:\\TGSSR\\test.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
在>=3.5中,您可以从执行的进程访问returncode
、stdout
和stderr
要捕获错误消息,请执行以下操作:
stdout, stderr = p.communicate()
# stdout = normal output
# stderr = error output
stdout = p.stdout # stdout = normal output
stderr = p.stderr # stderr = error output
检查流程返回代码:
if p.returncode != 0:
# handle error
if p.returncode != 0:
# handle error
虽然在windows上可能不需要,但如果不打算使用shell,则应将可执行文件作为列表传递:['C:\\TGSSR\\test.ext']
。此外,返回代码可能不可靠,因为(据我所知),仍然没有一种很好的标准化方法在Fortran中设置进程的返回代码。在这种情况下,p在两种状态下都为null(成功或失败)。所以我不能依赖它@mgilson:Popen(“程序”)
有效。它相当于POSIX上的Popen([“程序”])
。在Windows上,字符串参数始终有效。@user3161836:p
不为空;您的意思可能是p.returncode是None
。后者意味着这一过程尚未完成。你应该在p.communicate()
returns(它等待过程完成)之后检查p.returncode
。@mgilson:我真的忘了。谢谢你指出这一点。它应该是子进程。在这种情况下称为“进程错误”
。如果我只需要运行exe,我想我可以选择此选项。如果我这样做,我会弄错任何主要功能吗?这可能是措词不当,check_output是一个基于Popen的方便函数,它不需要自己处理stdout/stderr(在你的第一篇文章中,你实际上至少需要一个p.communicate()为了防止标准管道缓冲区完全填满(如果您使用FORTRAN工具输出了大量数据,这将有效地暂停执行)。不过,您可以轻松切换到Popen。Popen提供了更细粒度的进程创建控制:无关:为了避免转义反斜杠,可以使用原始字符串文本:r'C:\TGSSR\test.exe'
。不要在Windows上使用shell=True
,除非您使用shell功能,例如调用内置shell命令,如dir
。不要使用stdout=PIPE
,除非您稍后阅读p.stdout
谢谢您的评论!有时,错误会写入stdout/stderr之外(直接写入终端)。看见