简体   繁体   English

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

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

I'm trying to download a specific Docker image, where the user will input a version. 我正在尝试下载特定的Docker映像,用户将在其中输入版本。 However, if the version doesn't exist, Docker will throw an error. 但是,如果不存在该版本,则Docker将引发错误。

I'm using subprocess.call to pipe to the Terminal from Python 3. 我正在使用subprocess.call从Python 3管道到终端。

Sample code: 样例代码:

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)])

If the version isn't found, docker will output in the Terminal: 如果找不到版本,则docker将在终端中输出:

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

How do I catch this error within the Python script? 如何在Python脚本中捕获此错误?

Something along the lines of: 类似于以下内容:

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?`

If you are fine with the program writing its output to stderr and you not directly interacting with it, the easiest way to do what you are asking is to use check_call instead of call . 如果您对程序将其输出写入stderr感到满意,并且您不直接与它进行交互,那么执行要求的最简单方法是使用check_call而不是call check_call will raise an exception if the command it's running exits with anything other than 0 as its status. 如果正在运行的命令以状态非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")

You can use the Popen function of subprocess to grab the stderr and print in python console, as Documentation says for subprocess.call 您可以使用subprocess Popen函数来获取stderr并在python控制台中进行打印,如文档subprocess.call

Note Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. 注意请勿将stdout = PIPE或stderr = PIPE与此功能一起使用,因为这可能会基于子进程的输出量而死锁。 Use Popen with the communicate() method when you need pipes. 需要管道时,可以将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")

The answer above with checking the return code works but the more pythonic way would be to catch an exception like: 上面的检查返回代码的答案是可行的,但更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)

calledProcessError is the error caught by the Popen class. namedProcessError是Popen类捕获的错误。

If you want to catch the frequent errors on OS or system level (eg file/directory doesn't exist), add the following exceptions: 如果要捕获操作系统或系统级别的常见错误(例如,文件/目录不存在),请添加以下例外:

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

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

If you want to return a return code, you should do that explicitly instead of print()ing it. 如果要返回返回代码,则应明确地执行此操作,而不是对其进行print()处理。 Write after the last except statement and on the same indentation as the try statement: 在最后一个except语句之后并在与try语句相同的缩进位置上编写:

return True

If you want to return a message, you can use the Response object: 如果要返回消息,可以使用Response对象:

return Response ("Success Message")

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

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