如何处理 subprocess.run() error/exception

How to handle subprocess.run() error/exception

如何处理 Python 中的 subprocess.run() 错误?例如,我想 运行 cd + UserInputsubprocess.run()。如果用户键入不存在的目录名称怎么办?我该如何处理此类错误?

您可以使用 tryexpect 块来处理异常。

正如@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