Bash脚本迁移Azure ACR间Docker镜像:仅最后一个生效+格式错误
问题解决:Docker镜像跨ACR迁移脚本的两个问题修复
问题1:仅最后一个镜像完成拉取/推送
原因:for Image in \cat $FILE_NAME``的写法会将文件内容按空格/制表符/换行符拆分,若文件存在Windows格式换行符(\r\n),会导致所有行被错误解析为单个字符串,最终仅处理最后一个有效部分;同时这种写法无法兼容含空格的镜像名(虽不推荐,但需规避)。
解决方案:改用while read循环逐行读取文件,确保每行作为独立镜像名处理。
问题2:Docker镜像引用格式错误(含\r)
原因:linux-images.txt以Windows格式保存,每行末尾带有回车符\r,拼接后的镜像地址包含该字符,触发Docker的无效引用校验错误。
解决方案:
- 直接转换文件格式:用
dos2unix linux-images.txt将文件转为Unix格式(Debian/Ubuntu安装工具:sudo apt install dos2unix;CentOS/RHEL:sudo yum install dos2unix)。 - 脚本内处理:读取文件时自动去除
\r字符。
修复后的完整脚本
#!/bin/sh FILE_NAME="linux-images.txt" SOURCE_ACR_NAME="" SOURCE_USER_NAME="" SOURCE_PASSWORD="" DEST_ACR_NAME="" DEST_USER_NAME="" DEST_PASSWORD="" # 登录源ACR docker login -u "$SOURCE_USER_NAME" -p "$SOURCE_PASSWORD" "$SOURCE_ACR_NAME" # 登录目标ACR docker login -u "$DEST_USER_NAME" -p "$DEST_PASSWORD" "$DEST_ACR_NAME" # 逐行读取镜像名,兼容空行并去除Windows换行符 while IFS= read -r Image || [ -n "$Image" ]; do # 强制去除可能存在的\r字符 Image=$(echo "$Image" | tr -d '\r') # 跳过空行 [ -z "$Image" ] && continue SOURCE_IMAGE="$SOURCE_ACR_NAME/$Image" DEST_IMAGE="$DEST_ACR_NAME/$Image" echo "正在迁移镜像:$SOURCE_IMAGE -> $DEST_IMAGE" # 前一步成功才执行下一步,避免无效操作 docker pull "$SOURCE_IMAGE" && \ docker tag "$SOURCE_IMAGE" "$DEST_IMAGE" && \ docker push "$DEST_IMAGE" done < "$FILE_NAME" # 分别退出两个ACR的登录,更规范 docker logout "$SOURCE_ACR_NAME" docker logout "$DEST_ACR_NAME"
额外优化说明
- 用
&&串联Docker命令,确保拉取成功后再执行打标签、推送操作,减少无效流程。 - 增加空行判断,避免处理文件中的空白内容。
- 单独退出两个ACR的登录,比全局
docker logout更严谨。
内容的提问来源于stack exchange,提问作者Niraj Thakur
相关产品推荐
相关产品推荐

