简体   繁体   English

如何捕获子进程错误

[英]how to capture subprocess error

In Python, I run an exe made using FORTRAN. I use the subprocess module.在 Python 中,我运行了一个使用 FORTRAN 制作的 exe。我使用了subprocess模块。 that exe accesses and writes to several files.该exe访问并写入多个文件。 If I make those files readonly, I see the following trace in my Python console.如果我将这些文件设置为只读,我会在我的 Python 控制台中看到以下跟踪。

I tried by using try , except statements.我尝试使用try , except语句。 But I could not capture the error.但是我无法捕获错误。 I also tried using p.stdout.readline() .我也尝试使用p.stdout.readline() But was unsuccessful.但是没有成功。

Is there a systematic way to capture this sort of errors.是否有系统的方法来捕获此类错误。

Code:代码:

import subprocess
p = subprocess.Popen('C:\\TGSSR\\test.exe' , shell=True, stdout=subprocess.PIPE)

Traceback:追溯:

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

Run the process:运行流程:

p = subprocess.Popen(['C:\\TGSSR\\test.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# shell = True is not needed

To capture the error message:要捕获错误消息:

stdout, stderr = p.communicate()
# stdout = normal output
# stderr = error output

Check the process return code:检查进程返回码:

if p.returncode != 0:
    # handle error

Python 3.5 introduced the subprocess.run() method. Python 3.5 引入了subprocess.run()方法。

Here is the @kirbyfan64sos answer updated for Python >=3.5:这是针对 Python >=3.5 更新的 @kirbyfan64sos 答案:

Run the process:运行流程:

p = subprocess.run(['C:\\TGSSR\\test.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

In >=3.5, you can access the returncode , stdout , and stderr from the executed process.在 >=3.5 中,您可以从执行的进程中访问returncodestdoutstderr

To capture the error message:要捕获错误消息:

stdout = p.stdout # stdout = normal output
stderr = p.stderr # stderr = error output

Check the process return code:检查进程返回码:

if p.returncode != 0:
# handle error

If don't need all of Popen's functionality but just need to fetch stdout, you could also go for:如果不需要 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)

EDIT: As mgilson pointed out in the other answer, this requires a non-zero returncode on failures.编辑:正如 mgilson 在另一个答案中指出的那样,这需要在失败时使用非零返回码。 If that isn't the case, you could try something along the lines of:如果不是这种情况,您可以尝试以下方法:

output = subprocess.check_output('C:\\TGSSR\\test.exe')
if "permission to access file denied" in output:
    print("Failed")

with some string that will only be on stdout in case of an error一些字符串只会在出现错误时出现在标准输出上

In the majority of cases, you need to use subprocess.run.在大多数情况下,您需要使用 subprocess.run。 And to capture the error, you have to use the parameter "capture_output=True, check=True"要捕获错误,您必须使用参数“capture_output=True, check=True”

check=True is really necessary. check=True 真的很有必要。

try:
    subprocess.run(args, cwd, capture_output=True, check=True)
except subprocess.CalledProcessError as e:
    print("Error while executing YoloV5:")
    for k, v in e.__dict__.items():
        print(k)
        if isinstance(v, bytes):
            print(v.decode("utf-8"))
        else:
            print(v)
    raise Exception("Error in subcommand")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM