仅当具有给定名称的 Docker 容器不存在时,如何执行 Bash 命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38576337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:22:00  来源:igfitidea点击:

How to execute a Bash command only if a Docker container with a given name does not exist?

bashdocker

提问by kshah

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.

在 Jenkins 机器上,我想创建一个具有指定名称的 docker 容器,仅当它不存在时(在 shell 脚本中)。我想我可能会运行命令来创建容器,并且如果有失败则忽略失败,但这会导致我的 jenkins 工作失败。

Hence, I would like to know how I can check if a docker container exists or not using bash.

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

回答by ferdy

You can check for non-existence of a running container by grepping for a <name>and fire it up later on like this:

您可以通过搜索 a 来检查正在运行的容器是否不存在,<name>然后像这样启动它:

[ ! "$(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:

使用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

回答by anubhava

You can use filterand formatoptions for docker pscommand to avoid piping with unix utilities like grep, awketc.

您可以使用filterformat查看选项docker ps命令,以避免管道与UNIX工具一样grepawk等等。

name='nginx'

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

回答by WiRai

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.

因为 docker 容器检查调用将设置 $? 如果容器不存在(无法检查),则为 1,如果存在则为 0(这尊重已停止的容器)。因此,如果容器不按预期存在,则只会调用 run 命令。

回答by yucer

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

回答by Blaise

Even shorter with docker top:

更短的docker top

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

docker topreturns non-zero when there are no containers matching the name running, else it returns the pid, user, running time and command.

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

回答by Aliaksei Maniuk

I use following code to determine if docker container exists:

我使用以下代码来确定 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

回答by Fernando César

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.

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

So -f itIsTherewill return itIsThereif a container with that namex exits. If it doesn't, docker will return an error code and message (Error: No such object: <container-name>).

因此,-f itIsThere将返回itIsThere如果与namex出口的容器。如果没有,docker 将返回错误代码和消息 ( Error: No such object: <container-name>)。

I found this one in Jenkins logs.

我在 Jenkins 日志中找到了这个。

回答by GollyJer

Piggy-backing off of @Fernando César.
This checks for the container id from the given container name and suppresses error output ( 2> /dev/null).

支持@Fernando César。
这将检查给定容器名称中的容器 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

回答by rainabba

This is my solution to check for a running container, stop it, then remove it.

这是我检查正在运行的容器,停止它,然后将其删除的解决方案。

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 pslists RUNNING containers. docker ps -qdoes the same but the output is striped to include only the container_id. docker ps -alists ALL containers (running or not). docker ps -qathen is a simple list of all containers while docker ps -qis a simple list of running containers. docker ps -q -f name=ContainerNameis then a simple list of running containers with the name ContainerName. docker ps -qa -fwould 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).

我不得不多次搜索这个,因为即使上面的 100 多个答案实际上也不起作用。我认为原因是对docker ps的误解。docker ps列出正在运行的容器。docker ps -q执行相同的操作,但将输出条带化为仅包含 container_id。docker ps -a列出所有容器(运行与否)。docker ps -qathen 是所有容器的简单列表,而docker ps -q是正在运行的容器的简单列表。docker ps -q -f name=ContainerName然后是一个名为ContainerName 的正在运行的容器的简单列表。docker ps -qa -f也将包括退出的容器,因此逻辑必须是检查 -a(在那里,运行与否),然后没有 -a 来查看它是否不仅在那里,而且正在运行(并且需要先停止)。

回答by Namik Hajiyev

In bash script I check if container exists by name like this :

在 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