docker images
docker イメージを実行すると、複数のタグが付いたイメージと最新のタグ値が付いたイメージのリストが以下のように表示されます。
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
私は、タグと docker イメージ名for i in {docker image save -o <imagename>.tar}
を持つ docker イメージを除外し、大きい数字のタグのイメージのみを tar として保存したいと思います。 これを 1 行のコマンドで実現する方法を教えてください。latest
m4
答え1
bash を前提とすると、これを実行する「ワンライナー」は次のようになります。
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