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

时间:2016-07-25 19:56:40

标签: bash docker

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

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

12 个答案:

答案 0 :(得分:78)

您可以通过点击<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

答案 1 :(得分:24)

您可以对filter命令使用formatdocker ps选项,以避免使用grepawk等unix实用程序进行管道连接。

name='nginx'

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

答案 2 :(得分:14)

我想

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

因为docker container inspect调用会设置$?如果容器不存在(不能检查),则为1;如果确实存在,则为0(这意味着已停止的容器)。因此,只要容器不按预期存在,就会调用run命令。

答案 3 :(得分:6)

只需在名称前加上^ /,后缀加上$。这似乎是一个正则表达式:

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

答案 4 :(得分:2)

健壮的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/895245https://stackoverflow.com/a/43202632/895245依赖于我无法找到文档的行为:docker container inspect的退出状态以及-f name采用某种正则表达式。< / LI>

    <强>的Python

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

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

答案 5 :(得分:2)

docker top甚至更短:

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

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

答案 6 :(得分:2)

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

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

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

答案 7 :(得分:1)

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

答案 8 :(得分:0)

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

<强>解释

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

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

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

答案 9 :(得分:0)

@FernandoCé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

答案 10 :(得分:0)

在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

答案 11 :(得分:0)

re.finditer,如果要列出所有状态(已停止,正在运行等)
m.end(如果您只想列出正在运行的容器,则不需要)

-a

如果有1行或更多行,命令的状态码将为0。如果没有容器,则grep将以1状态码结尾。您可以通过以下方式处理它:

Windows

-f status=running

Linux

$ docker ps -f name=containerName | grep containerName

container is up and running

when container is stopped

see the properties of execSync 参考:https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/