当我执行 docker 图像时,我有下面的docker images
列表,其中有具有多个标签的图像以及具有最新标签值的图像。
REPOSITORY TAG IMAGE ID CREATED SIZE
m1 latest 40febdb010b1 15 minutes ago 479MB
m2 130 fab5a122127a 4 weeks ago 2.74GB
m2 115 5a2ee5c5f5e5 4 weeks ago 818MB
m3 111 dd91a7f68e3d 5 weeks ago 818MB
m3 23 0657662756f6 5 weeks ago 2.22GB
m4 23 0657662756f6 5 weeks ago 2.22GB
虽然我这样做,但for i in {docker image save -o <imagename>.tar}
我只想将图像保存为具有较高数字的标记的 tar,但任何带有latest
标记和 docker 图像名称的 docker 图像除外,如m4
如何在一个 liner 命令中实现这一点。
答案1
假设使用 bash,这里有一个“one-liner”可以做到这一点:
unset saved; declare -A saved; docker images --format '{{.Repository}} {{.Tag}}' | while read repo tag; do if [[ "$repo" == "m4" ]] || [[ "$tag" == latest ]]; then continue; fi; if [[ "${saved[$repo]}" != true ]]; then docker image save -o "$repo-$tag".tar "$repo:$tag"; saved["$repo"]=true; fi; done
分开一下就可以理解了:
unset saved
declare -A saved
docker images --format '{{.Repository}} {{.Tag}}' | while read repo tag; do
if [[ "$repo" == "m4" ]] || [[ "$tag" == latest ]]; then continue; fi
if [[ "${saved[$repo]}" != true ]]; then
docker image save -o "$repo-$tag".tar "$repo:$tag"
saved["$repo"]=true
fi
done
这声明了一个关联数组saved
,列出仅包含其存储库和标签的图像,跳过latest
图像,并保存图像(如果尚未保存存储库)。为了确定后者,当保存图像时,该事实被记录在数组中saved
;在保存图像之前,会检查数组以查看是否已保存具有相同存储库的图像。
docker images
列出从最新的图像开始的图像,因此只要有多个图像共享同一存储库(或名称),这将保存最新的图像。
没有对 tarball 名称进行特殊处理,因此它可能无法完成您对包含斜杠的存储库的操作。也无法处理没有存储库或标签的图像。以下较长版本会根据需要创建子目录并跳过未标记的图像:
unset saved
declare -A saved
docker images --format '{{.Repository}} {{.Tag}}' | while read repo tag; do
if [[ "$repo" == "m4" ]] || [[ "$tag" == latest ]] || [[ "$repo" == "<none>" ]] || [[ "$tag" == "<none>" ]]; then continue; fi
if [[ "${saved[$repo]}" != true ]]; then
if [[ "${repo}" =~ "/" ]]; then mkdir -p "${repo%/*}"; fi
docker image save -o "$repo-$tag".tar "$repo:$tag"
saved["$repo"]=true
fi
done