如何执行 Bash 命令,只有当一个 Docker 容器与给定的名称不存在?

在 Jenkins 机器上,我想创建一个带有指定名称的 docker 容器,只有在它不存在的情况下(在 shell 脚本中)。我认为我可以运行这个命令来创建容器,并忽略失败(如果有失败的话) ,但是这会导致我的 jenkins 作业失败。

因此,我想知道如何检查 docker 容器是否存在或不使用 bash。

137788 次浏览

你可以通过抓取一个 <name>来检查一个运行中的容器是否存在,然后像下面这样启动它:

[ ! "$(docker ps -a | grep <name>)" ] && docker run -d --name <name> <image>

更好的办法是:

使用 https://docs.docker.com/engine/reference/commandline/ps/并检查退出的容器是否阻塞,这样您可以在运行容器之前先移除它:

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

您可以对 docker ps命令使用 filterformat选项,以避免使用 Unix 实用程序(如 grepawk等)进行管道传输。

name='nginx'


[[ $(docker ps --filter "name=^/$name$" --format '\{\{.Names}}') == $name ]] ||
docker run -d --name mynginx <nginx-image>

只要在名字前面加上 ^/,后面加上 $就可以了。看起来它是一个正则表达式:

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

我想是吧

docker container inspect <container-name> || docker run...

因为码头集装箱检查呼叫将设置 $?如果容器不存在(不能检查)则为1,如果存在则为0(这涉及到已停止的容器)。因此,如果容器不像预期的那样存在,那么将调用 run 命令。

我使用以下代码来确定是否存在 Docker 容器:

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
if [[ $(sudo docker inspect --format . <container-name>) == "." ]]; then
docker run <container-name>;
fi

解说 :

已经有类似的反应了。这里的区别在于 --format .选项(您也可以使用 -f .)。这将删除视察命令中的所有详细信息。Docker 使用 模板格式,在这种情况下,这意味着它将把它不能识别的任何内容复制到输出。

因此,如果具有该名称的容器退出,则 -f itIsThere将返回 itIsThere。如果没有,docker 将返回一个错误代码和消息(Error: No such object: <container-name>)。

我在 Jenkins 的日志里找到了这个。

没有非文档化行为的稳健 grep ^$

这是我能找到的最精确、最灵活的方法:

container_name=mycont
if sudo docker ps -a --format '\{\{.Names}}' | grep -Eq "^${container_name}\$"; then
echo exists
else
echo 'does not exist'
fi

理由:

  1. 如果容器名是另一个容器中的子字符串,那么 https://stackoverflow.com/a/38576401/895245 就不起作用
  2. Https://stackoverflow.com/a/45171589/895245 https://stackoverflow.com/a/43202632/895245依赖于我找不到文档的行为: docker container inspect的退出状态和 -f name采用某种正则表达式。

巨蟒

一个方便的 Python 版本,因为我最终在一个项目中使用了它:

containers = subprocess.check_output([
'sudo',
'docker',
'ps',
'-a',
'--format', '\{\{.Names}}',
]).decode()
if container_name in containers.split():
# Exists.

码头上衣的时间更短:

docker top <name> || docker run --name <name> <image>

当没有与运行名称匹配的容器时,docker top返回非零值,否则返回 pid、 user、运行时间和命令。

从“费尔南多 · 塞萨尔”身边滚开。
这将检查给定容器名称中的容器 ID,并抑制错误输出(2> /dev/null)。

CONTAINER_NAME="awesome-container"


CONTAINER_ID=$(docker inspect --format="\{\{.Id}}" ${CONTAINER_NAME} 2> /dev/null)
if [[ "${CONTAINER_ID}" ]]; then
# container found.
else
# container not found.
fi

这是我的解决方案,检查一个运行的容器,停止它,然后删除它。

CNAME=$CONTAINER_NAME-$CODE_VERSION
if [ "$(docker ps -qa -f name=$CNAME)" ]; then
echo ":: Found container - $CNAME"
if [ "$(docker ps -q -f name=$CNAME)" ]; then
echo ":: Stopping running container - $CNAME"
docker stop $CNAME;
fi
echo ":: Removing stopped container - $CNAME"
docker rm $CNAME;
fi

I've had to search this too many times because even the 100+ answer above doesn't actually work. I think the reason is a misunderstanding on docker ps. docker ps lists RUNNING containers. docker ps -q does the same but the output is striped to include only the container_id. docker ps -a lists ALL containers (running or not). docker ps -qa then is a simple list of all containers while docker ps -q is a simple list of running containers. docker ps -q -f name=ContainerName is then a simple list of running containers with the name ContainerName. docker ps -qa -f would include exited containers as well so the logic must be to check -a (there, running or not), then without -a to see if it's not only there, but running (and needs to be stopped first).

在 bash 脚本中,我检查容器是否按如下名称存在:

CONTAINER_NAME="my-container-name"
if ! docker container ls -a | grep -Fq "$CONTAINER_NAME" 1>/dev/null; then
echo "could not found container $CONTAINER_NAME..."
fi

-a if you want to list all states (stopped, running etc.)
-f status=running(如果只想列出正在运行的容器,则不需要)

$ docker ps -f name=containerName | grep containerName

如果有一行或多行状态代码的命令将为0。如果没有容器,grep 将以1状态代码结束。你可以通过以下方式来处理:

窗户

$ echo %errorlevel%

Linux

$ echo $?

container is up and running

when container is stopped

see the properties of execSync 参考文献: < a href = “ https://www.Cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/”rel = “ nofollow norefrer”> https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/

下面是一个按确切名称检查船坞容器是否存在的示例:

(docker ps -a --format \{\{.Names}} | grep container_name -w) && echo Exists || echo "Doesn't exist"

跳过退出的容器:-

CONTAINER_NAME=xyz
if [ ! "$(docker ps -a | grep ${CONTAINER_NAME} | grep -v Exited)" ]; then echo "${CONTAINER_NAME} is not running"; else echo "${CONTAINER_NAME} is running"; fi