我使用以下代码来测试向 shell 发送命令时的错误捕获:
#!/usr/bin/python3
'''Trying to get a better error capture for subprocess.run'''
import subprocess
import argparse
cmd = 'ixconfig'
useShell = False
if useShell:
myCommand = cmd
else:
myCommand = cmd.split()
try:
result = subprocess.run(myCommand,
capture_output=True,
check=True,
shell=useShell,
text=True,
timeout=1,
)
except subprocess.TimeoutExpired:
print('Timeout occurred')
result = argparse.Namespace(err=f'"{myCommand}" timed out')
except subprocess.CalledProcessError as subErr:
print('subprocess.CalledProcessError')
result = argparse.Namespace(err=subErr)
except subprocess.SubprocessError as subErr:
print('except subprocess.SubprocessError')
result = argparse.Namespace(err=subErr)
# except:
# result = 'Poor way to handle an exception'
print(f'{result=}')
在大多数情况下它是有效的。当我尝试列出无效目录 (
cmd = 'ls /var/log/xxx'
) 或超时 (cmd = 'sleep 5'
) 时,我可能会收到 CalledProcessError。
但是,如果我发送错误的命令,例如
cmd = 'ixconfig'
,我会得到回溯而不是通过 SubprocessError 捕获:
Traceback (most recent call last):
File "/Users/shepherd/prog/aws/BBEditRunTemp-testSubprocess.py", line 17, in <module>
result = subprocess.run(myCommand,
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 489, in run
with Popen(*popenargs, **kwargs) as process:
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 854, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 1702, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'ixconfig'
如果我取消注释直接的
except:
部分,异常会被正确捕获,但我知道裸异常是糟糕的编程。如何正确捕获正确的运行时异常?
@andrej-kesely 提供了有效的答案:
except FileNotFoundError as subErr:
print('FileNotFoundError')
result = argparse.Namespace(err=subErr)