如何用Shell脚本检测Docker镜像Tag是否存在于仓库并按需推送
实现方案
前置依赖
需要先安装jq工具用于JSON解析,主流Linux发行版可以直接通过包管理器安装:
- Debian/Ubuntu:
apt install jq - RHEL/CentOS:
yum install jq - macOS:
brew install jq
适配你现有数组逻辑的实现
如果你已经通过sed将镜像和标签拆分到arraydata数组中,在遍历每个镜像的循环中使用以下逻辑即可:
image=${arraydata[0]} tag=${arraydata[1]} # 静默请求镜像标签列表,判断目标标签是否存在 tag_exists=$(curl -s -f "https://docker.jfrog.io/artifactory/api/docker/docker-local/v2/$image/tags/list" | jq --arg target_tag "$tag" '.tags | index($target_tag) != null') if [ "$tag_exists" = "true" ]; then echo "镜像 $image:$tag 已存在,跳过推送" else echo "镜像 $image:$tag 不存在,执行推送" docker push "jfrog/$image:$tag" fi
更稳定的完整实现(无需手动解析images.json)
直接通过jq读取images.json的内容遍历处理,同时增加了请求错误处理、推送结果校验逻辑,更适合生产环境使用:
#!/bin/bash # 检查jq是否已安装 if ! command -v jq &> /dev/null; then echo "错误:请先安装jq工具后再运行脚本" exit 1 fi # 遍历images.json中的所有镜像和对应标签 jq -r 'to_entries[] | "\(.key) \(.value)"' images.json | while read -r image tag; do echo "正在检查 $image:$tag 的仓库存在状态..." # 请求标签列表,同时获取HTTP状态码处理异常情况 response=$(curl -s -w "HTTP_STATUS:%{http_code}" "https://docker.jfrog.io/artifactory/api/docker/docker-local/v2/$image/tags/list") http_status=$(echo "$response" | grep -o 'HTTP_STATUS:[0-9]*' | cut -d: -f2) tag_content=$(echo "$response" | sed 's/HTTP_STATUS:[0-9]*$//') push_flag=1 if [ "$http_status" -eq 200 ]; then # 接口请求成功,判断标签是否存在 tag_in_repo=$(echo "$tag_content" | jq --arg t "$tag" '.tags | index($t) != null') if [ "$tag_in_repo" = "true" ]; then echo "✅ $image:$tag 已存在于仓库,跳过推送" push_flag=0 fi fi if [ $push_flag -eq 1 ]; then echo "⏳ 开始推送 $image:$tag..." docker push "jfrog/$image:$tag" if [ $? -eq 0 ]; then echo "✅ $image:$tag 推送成功" else echo "❌ $image:$tag 推送失败" fi fi done
逻辑说明
- 优先使用
jq解析JSON返回结果,比字符串匹配准确率更高,不会出现标签名和其他字段重名导致的误判 - 增加了HTTP状态码判断,若镜像本身不存在于仓库(接口返回404)会直接触发推送逻辑
- 增加了推送结果校验,运行日志清晰可查
内容的提问来源于stack exchange,提问作者gmpy1990
相关产品推荐
相关产品推荐

