簡體   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