Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何检查带有特定标记的Docker图像是否在本地存在?_Bash_Docker - Fatal编程技术网

Bash 如何检查带有特定标记的Docker图像是否在本地存在?

Bash 如何检查带有特定标记的Docker图像是否在本地存在?,bash,docker,Bash,Docker,我想知道本地是否存在带有特定标记的Docker映像。如果Docker客户端无法在本机上执行此操作,则可以使用bash脚本 为了给可能的bash脚本提供一些提示,运行docker images命令的结果返回以下内容: REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE rabbitmq

我想知道本地是否存在带有特定标记的Docker映像。如果Docker客户端无法在本机上执行此操作,则可以使用bash脚本

为了给可能的bash脚本提供一些提示,运行
docker images
命令的结果返回以下内容:

REPOSITORY                               TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
rabbitmq                                 latest              e8e654c05c91        5 weeks ago         143.5 MB
busybox                                  latest              8c2e06607696        6 weeks ago         2.433 MB
rabbitmq                                 3.4.4               a4fbaad9f996        11 weeks ago        131.5 MB
[ -n "$(docker images -q someimage:sometag)" ] || echo "does not exist"

我通常测试(如中)的结果:

但由于
docker images
仅将
存储库
作为参数,因此需要在标记上grep,而不使用
-q

立即获取标签(docker 1.8+)
[存储库[:标签]]

下面提到的另一种方法是使用。
但对于docker 17+,图像的语法是:(对于不存在的图像,则为)

如中所述:

  • docker images-q
    方法在有大量图像的机器上会变得非常慢。在6500映像计算机上运行需要44秒
  • docker图像检查立即返回
在上面的帮助下,我创建了以下名为
check.sh的bash脚本:

#!/bin/bash
image_and_tag="$1"
image_and_tag_array=(${image_and_tag//:/ })
if [[ "$(docker images ${image_and_tag_array[0]} | grep ${image_and_tag_array[1]} 2> /dev/null)" != "" ]]; then
  echo "exists"
else
  echo "doesn't exist"
fi
将其用于现有图像和标签将打印
exists
,例如:

./check.sh rabbitmq:3.4.4
./check.sh rabbitmq:3.4.3
$ docker inspect --type=image treeder/hello.rb:nada
Error: No such image: treeder/hello.rb:nada
[]
将其用于不存在的图像和标签将打印
不存在
,例如:

./check.sh rabbitmq:3.4.4
./check.sh rabbitmq:3.4.3
$ docker inspect --type=image treeder/hello.rb:nada
Error: No such image: treeder/hello.rb:nada
[]

尝试
docker inspect
,例如:

./check.sh rabbitmq:3.4.4
./check.sh rabbitmq:3.4.3
$ docker inspect --type=image treeder/hello.rb:nada
Error: No such image: treeder/hello.rb:nada
[]
但是现在有了一个存在的图像,您将获得一系列信息,例如:

$ docker inspect --type=image treeder/hello.rb:latest
[
{
    "Id": "85c5116a2835521de2c52f10ab5dda0ff002a4a12aa476c141aace9bc67f43ad",
    "Parent": "ecf63f5eb5e89e5974875da3998d72abc0d3d0e4ae2354887fffba037b356ad5",
    "Comment": "",
    "Created": "2015-09-23T22:06:38.86684783Z",
    ...
}
]

而且它是一种很好的json格式

您可以像下面这样使用:

REPOSITORY                               TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
rabbitmq                                 latest              e8e654c05c91        5 weeks ago         143.5 MB
busybox                                  latest              8c2e06607696        6 weeks ago         2.433 MB
rabbitmq                                 3.4.4               a4fbaad9f996        11 weeks ago        131.5 MB
[ -n "$(docker images -q someimage:sometag)" ] || echo "does not exist"
或:

tldr:

通过演示

成功,找到图像:

$ docker image pull busybox:latest
latest: Pulling from library/busybox
Digest: sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f
Status: Image is up to date for busybox:latest

$ docker image inspect busybox:latest >/dev/null 2>&1 && echo yes || echo no
yes
失败,缺少图像:

$ docker image rm busybox:latest
Untagged: busybox:latest
Untagged: busybox@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f

$ docker image inspect busybox:latest >/dev/null 2>&1 && echo yes || echo no
no
参考:


使用
测试

if test ! -z "$(docker images -q <name:tag>)"; then
  echo "Exist"
fi
如果测试-z“$(docker images-q)”;然后
回声“存在”
fi
还是一行

test ! -z "$(docker images -q <name:tag>)" &&  echo exist
测试-z“$(docker images-q)”和回音存在(&E)

如果您试图从docker注册表中搜索docker映像,我想检查是否存在docker映像的最简单方法是使用

示例:-

curl $CURLOPTS -H "Authorization: Bearer $token" "https://hub.docker.com:4443/v2/your-repo-name/tags/list"
如果上面的结果返回200Ok和图像标记列表,那么我们知道图像存在

{"name":"your-repo-name","tags":["1.0.0.1533677221","1.0.0.1533740305","1.0.0.1535659921","1.0.0.1535665433","latest"]}
如果你看到像这样的东西

{"errors":[{"code":"NAME_UNKNOWN","message":"repository name not known to registry","detail":{"name":"your-repo-name"}}]} 

那么你肯定知道这张图片不存在。

我对非常好的读者说:

建造
#/bin/bash-e
docker构建-t smpp网关smpp
(如果[$(docker ps-a | grep smpp网关| cut-d”“-f1)],则\
echo$(docker rm-f smpp网关)\
否则\
回声正常\
fi;);
docker运行--始终重新启动-d--network=“host”--名称smpp网关smpp网关:最新
监视
docker日志--尾部50--跟随--时间戳smpp网关
sudo docker exec-it\
$(sudo docker ps | grep“smpp网关:最新的”| cut-d“-f1)\
/bin/bash
用于特定标记名

$ docker images  --filter reference='<REPOSITORY>:TAG'

在bash脚本中,我这样做是为了通过标记检查图像是否存在:

IMAGE_NAME="mysql:5.6"

if docker image ls -a "$IMAGE_NAME" | grep -Fq "$IMAGE_NAME" 1>/dev/null; then
echo "could found image $IMAGE_NAME..."
fi
上面的示例脚本检查带有5.6标记的mysql图像是否存在。如果您想检查是否存在任何没有特定版本的mysql映像,则只需传递存储库名称而不带标记,如下所示:

IMAGE_NAME="mysql"

我认为这个功能应该在
docker build
命令中实现(使用标志?),这样可以避免大量代码重复

我使用了与名为
docker\u build
的包装函数内部相同的条件,以便它在调用原始
docker build
命令之前进行必要的检查

# Usage: docker_build <...> (instead of docker build)

docker_build()
{
    local arguments=("$@")
    local index
    for (( index=0; index<$#; index++ )); do
        case ${arguments[index]} in
            --tag)
                local tag=${arguments[index+1]}
                if [[ ! -z $(docker images -q "${tag}" 2> /dev/null) ]]; then
                    echo "Image ${tag} already exists."
                    return
                fi
                ;;
        esac
    done
    command docker build "$@"
}
用法:docker构建(而不是docker构建) docker_build() { 局部参数=(“$@”) 局部索引 对于((index=0;index/dev/null)];然后 echo“图像${tag}已存在。” 返回 fi ;; 以撒 完成 命令docker生成“$@” }
免责声明:此命令尚未准备就绪,因为它仅适用于长格式的空格分隔参数,即
--tag hello world:latest
。此外,此命令仅修改
docker build
命令,所有其他命令保持不变。如果有人有改进,请告诉我


我很想分享这段代码,因为在bash函数中包装标准命令以避免代码重复的想法似乎比编写包装语句更优雅、更具可扩展性。

受@rubicks上述反应的启发

检查图像是否已存在

image_name_tag="alpine:3.13.3"

docker image inspect ${image_name_tag} > /dev/null
echo $?
如果图像不存在则拉取

docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
演示执行

# image_name_tag="alpine:3.13.3"
# 
# docker image inspect ${image_name_tag} > /dev/null
echo $?
Error: No such image: alpine:3.13.3
# echo $?
1
# docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
Error: No such image: alpine:3.13.3
3.13.3: Pulling from library/alpine
9aae54b2144e: Pull complete 
Digest: sha256:826f70e0ac33e99a72cf20fb0571245a8fee52d68cb26d8bc58e53bfa65dcdfa
Status: Downloaded newer image for alpine:3.13.3
docker.io/library/alpine:3.13.3
# docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
$ 

嗯,不确定这是否适用于标记?当我执行“docker images-q rabbitmq”时,它返回“e8e654c05c91和a4fbaad9f996”,但如果执行“docker images-q rabbitmq:3.4.4”即使标记存在,也不会返回任何内容。@Johan即使标记存在于本地?@Johan我刚刚仔细检查了docker images参数,并且docker images参数实际上只获取repo,而不是标记。我编辑了答案以提出替代解决方案。谢谢,这似乎可行。但也许您应该编辑答案并从中删除“:mytag”“我的图像:我的标签”在我接受它之前?对于新手来说:图像(我的图像)和标签(我的标签)有什么不同?为什么myimage:mytag而不仅仅是mytag?不起作用,至少在macOS上,返回值总是0。代码是正确的,在linux上可以工作。我唯一要添加的是在子shell中加引号command@GaborCsardi这一款适用于MacOS:
[[-z”$(docker images-q someimage:sometag)].\124; echo“存在”
以及
[-n”$(docker images-q someimage:sometag)]]|echo“不存在”
。编辑的答案。现在应该可以正常工作了。Gabor,你能确认一下吗?这是最容易编写的答案。事实上,
images
ps
命令总是以0退出,而
inspect
则很简单:
docker inspect”${image\u id}:${image\tag“>/dev/null 2>&1 | | echo“不存在!”
docker inspect
非常好,因为在不存在图像时返回非零代码。这也比