可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
On a Jenkins machine I would like to create a docker container with a specified name only if it does not already exist (in a shell script). I thought I might run the command to create the container regardless and ignore the failure if there was one, but this causes my jenkins job to fail.
Hence, I would like to know how I can check if a docker container exists or not using bash.
回答1:
You can check for non-existence of a running container by grepping for a <name>
and fire it up later on like this:
[ ! "$(docker ps -a | grep <name>)" ] && docker run -d --name <name> <image>
Better:
Make use of https://docs.docker.com/engine/reference/commandline/ps/ and check if an exited container blocks, so you can remove it first prior to run the container:
if [ ! "$(docker ps -q -f name=<name>)" ]; then
if [ "$(docker ps -aq -f status=exited -f name=<name>)" ]; then
# cleanup
docker rm <name>
fi
# run your container
docker run -d --name <name> my-docker-image
fi
回答2:
You can use filter
and format
options for docker ps
command to avoid piping with unix utilities like grep
, awk
etc.
name='nginx'
[[ $(docker ps --filter "name=^/$name$" --format '{{.Names}}') == $name ]] ||
docker run -d --name mynginx <nginx-image>
回答3:
I suppose
docker container inspect <container-name> || docker run...
since docker container inspect call will set $? to 1 if container does not exist (cannot inspect) but to 0 if it does exist (this respects stopped containers). So the run command will just be called in case container does not exist as expected.
回答4:
Just prefix the name with ^/ and suffix with $. It seems that it is a regular expression:
CONTAINER_NAME='mycontainername'
CID=$(docker ps -q -f status=running -f name=^/${CONTAINER_NAME}$)
if [ ! "${CID}" ]; then
echo "Container doesn't exist"
fi
unset CID
回答5:
I use following code to determine if docker container exists:
CONTAINER_NAME='my_docker_container'
# Checking if docker container with $CONTAINER_NAME name exists.
COUNT=$(docker ps -a | grep "$CONTAINER_NAME" | wc -l)
if (($COUNT > 0)); then
echo 'container exists'
fi
回答6:
Even shorter with docker top:
docker top <name> || docker run --name <name> <image>
docker top
returns non-zero when there are no containers matching the name running, else it returns the pid, user, running time and command.
回答7:
Robust grep ^$
without undocumented behavior
This is the most precise and flexible approach I could find:
container_name=mycont
if sudo docker ps -a --format '{{.Names}}' | grep -Eq "^${container_name}\$"; then
echo exists
else
echo 'does not exist'
fi
Rationale:
- https://stackoverflow.com/a/38576401/895245 doesn't work if the container name is a substring in another container
- https://stackoverflow.com/a/45171589/895245 and https://stackoverflow.com/a/43202632/895245 rely on behaviors for which I could not find the documentation: the exit status of
docker container inspect
and that -f name
takes regular expressions of some kind.
Python
A Python version for convenience since I ended up using it in a project:
containers = subprocess.check_output([
'sudo',
'docker',
'ps',
'-a',
'--format', '{{.Names}}',
]).decode()
if container_name in containers.split():
# Exists.
回答8:
if [[ $(sudo docker inspect --format . <container-name>) == "." ]]; then
docker run <container-name>;
fi
Explanation:
There is a similar response already. The difference here is the --format .
option (you can also use -f .
). This removes all the details from the inspect command. Docker uses the go template format, which in this case means that it will copy to the output anything it does not recognize.
So -f itIsThere
will return itIsThere
if a container with that namex exits. If it doesn't, docker will return an error code and message (Error: No such object: <container-name>
).
I found this one in Jenkins logs.