繁体   English   中英

如何使用Python捕获subprocess.call错误?

[英]How do I catch a subprocess.call error with Python?

我正在尝试下载特定的Docker映像,用户将在其中输入版本。 但是,如果不存在该版本,则Docker将引发错误。

我正在使用subprocess.call从Python 3管道到终端。

样例代码:

from subprocess import call
containerName = input("Enter Docker container name: ")
swVersion = input("Enter software version: ")

call(["docker", "run", "--name", "{}".format(containerName), 
      "--detach", "--publish", "8080:8080", "user/software:{}".format(swVersion)])

如果找不到版本,则docker将在终端中输出:

docker: Error response from daemon: manifest for user/software:8712378 not found.

如何在Python脚本中捕获此错误?

类似于以下内容:

try:
    call(["docker", "run", "--name", "{}".format(containerName), "--detach", "--publish", "8080:8080", "user/software:{}".format(swVersion)])
except:
    # How do I catch the piped response code here?`

如果您对程序将其输出写入stderr感到满意,并且您不直接与它进行交互,那么执行要求的最简单方法是使用check_call而不是call 如果正在运行的命令以状态非0退出,则check_call将引发异常。

try:
    check_call(["docker", "run", "--name", "{}".format(containerName), "--detach", "--publish", "8080:8080", "user/software:{}".format(swVersion)])
except CalledProcessError:
    print("That command didn't work, try again")

您可以使用subprocess Popen函数来获取stderr并在python控制台中进行打印,如文档subprocess.call

注意请勿将stdout = PIPE或stderr = PIPE与此功能一起使用,因为这可能会基于子进程的输出量而死锁。 需要管道时,可以将Popen与communication()方法一起使用。

proc = subprocess.Popen(["docker", "run", "--name", "{}".format(containerName), "--detach", "--publish", "8080:8080", "user/software:{}".format(swVersion)],stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=subprocess_flags)
proc.wait()
(stdout, stderr) = proc.communicate()

if proc.returncode != 0:
    print(stderr)
else:
    print("success")

上面的检查返回代码的答案是可行的,但更Python化的方式是捕获类似以下的异常:

try:
    proc = subprocess.Popen(["docker", "run", "--name", "{}".format(containerName), "--detach", "--publish", "8080:8080", "user/software:{}".format(swVersion)],stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=subprocess_flags)
    proc.wait()
    (stdout, stderr) = proc.communicate()

except calledProcessError as err:
    print("Error ocurred: " + err.stderr)

namedProcessError是Popen类捕获的错误。

如果要捕获操作系统或系统级别的常见错误(例如,文件/目录不存在),请添加以下例外:

except OSError as e:
    print ("OSError > ",e.errno)
    print ("OSError > ",e.strerror)
    print ("OSError > ",e.filename)

except:
    print ("Error > ",sys.exc_info()[0])

如果要返回返回代码,则应明确地执行此操作,而不是对其进行print()处理。 在最后一个except语句之后并在与try语句相同的缩进位置上编写:

return True

如果要返回消息,可以使用Response对象:

return Response ("Success Message")

暂无
暂无

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

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