如何处理 subprocess.run() error/exception
How to handle subprocess.run() error/exception
如何处理 Python 中的 subprocess.run()
错误?例如,我想 运行 cd + UserInput
和 subprocess.run()
。如果用户键入不存在的目录名称怎么办?我该如何处理此类错误?
您可以使用 try
和 expect
块来处理异常。
正如@match 提到的,您不能将 运行 cd
作为子进程,因为 cd
不是程序,它是 shell 内置的-在命令中。
但是如果您询问任何子流程失败,除了 cd
:
try:
subprocess.run(command_that_might_not_exist) # like ['abcd']
except Exception:
# handle the error
result = subprocess.run(command_that_might_fail) # like ['ls', 'abcd/']
if result.returncode != 0:
# handle the error
在子进程中 运行ning cd
没有任何用处。子进程将更改自己的目录,然后立即退出,不会在父进程或其他任何地方留下任何可观察到的变化。
出于同样的原因,在大多数系统上没有名为 cd
的二进制命令; cd
命令是 shell 内置的。
通常,如果您 运行 subprocess.run()
没有 check=True
关键字参数,子进程中的任何错误都将被忽略。所以如果 /bin/cd
或类似的命令存在,你可以 运行
# purely theoretical, and utterly useless
subprocess.run(['cd', UserInput])
而且根本不知道它是否做了任何事情。
如果你提供 check=True
,你需要捕获的异常是 CalledProcessError
:
try:
# pointless code as such; see explanation above
subprocess.run(['cd', UserInput], check=True)
except subprocess.CalledProcessError:
print('Directory name %s misspelled, or you lack the permissions' % UserInput)
但更根本的是,允许用户通过 运行 在子进程中任意未经检查的输入来刺激系统是一个可怕的想法。 (允许用户 运行 带有 shell=True
的任意 shell 脚本是一个 巨大的、灾难性的 可怕的想法,所以我们甚至不要去那里。也许看到 Actual meaning of shell=True
in subprocess
)
一种更安全的方法是 运行 带有 cwd=
关键字参数的子进程。
# also vaguely pointless
subprocess.run(['true'], cwd=UserInput)
在这种情况下,如果目录不存在,您可以期待一个常规的 FileNotFoundError
,或者如果您没有权限,则可以期待一个 PermissionError
。
您可能仍应添加 check=True
并准备好处理任何由此产生的异常,除非您特别不关心子进程是否成功。 (实际上在某些情况下这是有道理的,比如当你 grep
找某事但没有找到任何匹配时没关系,如果你使用 check=True
就会引发错误。)
或许还可以看看 Running Bash commands in Python
如何处理 Python 中的 subprocess.run()
错误?例如,我想 运行 cd + UserInput
和 subprocess.run()
。如果用户键入不存在的目录名称怎么办?我该如何处理此类错误?
您可以使用 try
和 expect
块来处理异常。
正如@match 提到的,您不能将 运行 cd
作为子进程,因为 cd
不是程序,它是 shell 内置的-在命令中。
但是如果您询问任何子流程失败,除了 cd
:
try:
subprocess.run(command_that_might_not_exist) # like ['abcd']
except Exception:
# handle the error
result = subprocess.run(command_that_might_fail) # like ['ls', 'abcd/']
if result.returncode != 0:
# handle the error
在子进程中 运行ning cd
没有任何用处。子进程将更改自己的目录,然后立即退出,不会在父进程或其他任何地方留下任何可观察到的变化。
出于同样的原因,在大多数系统上没有名为 cd
的二进制命令; cd
命令是 shell 内置的。
通常,如果您 运行 subprocess.run()
没有 check=True
关键字参数,子进程中的任何错误都将被忽略。所以如果 /bin/cd
或类似的命令存在,你可以 运行
# purely theoretical, and utterly useless
subprocess.run(['cd', UserInput])
而且根本不知道它是否做了任何事情。
如果你提供 check=True
,你需要捕获的异常是 CalledProcessError
:
try:
# pointless code as such; see explanation above
subprocess.run(['cd', UserInput], check=True)
except subprocess.CalledProcessError:
print('Directory name %s misspelled, or you lack the permissions' % UserInput)
但更根本的是,允许用户通过 运行 在子进程中任意未经检查的输入来刺激系统是一个可怕的想法。 (允许用户 运行 带有 shell=True
的任意 shell 脚本是一个 巨大的、灾难性的 可怕的想法,所以我们甚至不要去那里。也许看到 Actual meaning of shell=True
in subprocess
)
一种更安全的方法是 运行 带有 cwd=
关键字参数的子进程。
# also vaguely pointless
subprocess.run(['true'], cwd=UserInput)
在这种情况下,如果目录不存在,您可以期待一个常规的 FileNotFoundError
,或者如果您没有权限,则可以期待一个 PermissionError
。
您可能仍应添加 check=True
并准备好处理任何由此产生的异常,除非您特别不关心子进程是否成功。 (实际上在某些情况下这是有道理的,比如当你 grep
找某事但没有找到任何匹配时没关系,如果你使用 check=True
就会引发错误。)
或许还可以看看 Running Bash commands in Python