I'm trying to download a specific Docker image, where the user will input a version. However, if the version doesn't exist, Docker will throw an error.
I'm using subprocess.call
to pipe to the Terminal from 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: Error response from daemon: manifest for user/software:8712378 not found.
How do I catch this error within the Python script?
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
. check_call
will raise an exception if the command it's running exits with anything other than 0
as its status.
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
Note Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. Use Popen with the communicate() method when you need pipes.
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:
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.
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. Write after the last except statement and on the same indentation as the try statement:
return True
If you want to return a message, you can use the Response object:
return Response ("Success Message")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.