如果命令无效,在Python 3.4中调用子流程并处理错误?

我正在尝试在Python 3.4中执行外部过程.当我的“命令”错误时,程序崩溃.我该如何优雅地处理错误并恢复?

    # Call a system process
    try:
        pipe = subprocess.Popen(command,
                                stdout=subprocess.PIPE)
    except (OSError,
            subprocess.CalledProcessError) as error:
        print("Failed to execute command")
        print(command)
        print("Error: " + error.output)

    while True:
        output = pipe.stdout.readline()
        if not output:
            print("Finished...")
            break

        output = output.decode()
        output = output.strip("\r")
        output = output.strip("\n")
        print(output)

当我调用无效命令时.我遇到类似的崩溃:

C:\SDKs\Python34\python.exe C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\main.py
Traceback (most recent call last):
Executing:  windeployqt.exe  C:\Users\user\Documents\GitHub\SpaCentralSoftBin\GUIController.exe
  File "C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\forms\maindialog.py", line 81, in execute_windeployqt
Failed to execute command
    stdout=subprocess.PIPE)
windeployqt.exe  C:\Users\user\Documents\GitHub\SpaCentralSoftBin\GUIController.exe
  File "C:\SDKs\Python34\lib\subprocess.py", line 858, in __init__
    restore_signals, start_new_session)
  File "C:\SDKs\Python34\lib\subprocess.py", line 1111, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\forms\maindialog.py", line 159, in on_buttonBox_clicked
    self.execute_windeployqt()
  File "C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\forms\maindialog.py", line 86, in execute_windeployqt
    print("Error: " + error.output)
AttributeError: 'FileNotFoundError' object has no attribute 'output'

解决方法:

更大的问题是,打印错误消息不会以任何有意义的“处理”意义来“处理”错误(尽管许多人认为这样做).

如果需要,请记录一条错误消息,然后退出程序.在少数情况下,您可以处理错误,例如,如果无法读取配置文件,查看是否可以读取全局配置文件或KeyboardInterrupt可以传递给正在读取命令的主循环,则该错误很少.

在您的示例中,如果您没有在except块中出错,则输出= pipe.stdout …将产生:

NameError: name 'pipe' is not defined

如果发现了该错误,则仍然没有任何有意义的事情可恢复代码预期的状态.您还将移动回溯到没有错误的地方.

一个适合您情况的成语是

except SomeError:
    log what you want
    raise

空提升将重新引发最后一个异常,该异常将向上传播,从而形成完整的堆栈跟踪,从而使您可以更好地了解故障所在.如果您不这样做,则会丢弃有用的信息.

上一篇:python-subprocess.Popen,从子进程中获取变量(子)


下一篇:如何从python cgi脚本的子过程中捕获错误?