Docker 删除多张图片并保留最后两张

Docker remove multiple images and keep last two

我想做的是删除所有图像,只保留每个构建的最后两个图像。我几乎已经做到了这一点,但我收到了一些 docker rmi 错误,尽管脚本成功删除了我不需要的图像。另外,如果有办法使它更精确或更干净,请很高兴获得帮助。

docker 图片

REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
Mystg.azurecr.io/repo/api01      prod-20210402-43    fd01be2be633        54 minutes ago      201 MB
Mystg.azurecr.io/repo/api01      qa-20210401-5       6783fc21395f        23 hours ago        217 MB
Mystg.azurecr.io/repo/api02      qa-20210401-33      241107762154        23 hours ago        232 MB
Mystg.azurecr.io/repo/api02      prod-20210331-19      51a8f604b1bc        2 days ago          201 MB
Mystg.azurecr.io/repo/api02      qa-20210329-32      28a750d97d74        3 days ago          232 MB
Mystg.azurecr.io/repo/api02      prod-20210325-5       3d1004b7b97f        8 days ago          233 MB
Mystg.azurecr.io/repo/api02      prod-20210325-18      9d6c34c0623b        8 days ago          201 MB
Mystg.azurecr.io/repo/api02      qa-20210324-43      7a3d071b91b0        8 days ago          222 MB

代码

#!/bin/bash
pqimage=$(<images.txt)

timestamp=$(date +%Y%m%d_%H%M%S)
log_path="`pwd`"
filename=docker_cleanup_$timestamp.log
log=$log_path/$filename

docker_space_before(){
CURRENTSPACE=`docker system df`
echo "Current Docker Space:"
echo $CURRENTSPACE >> $log
}

for PRIMAGES in ${pqimage}; do
docker images | grep  "M*/$PRIMAGES" | grep "prod-2021*" | tail -n +3 >> $log
sudo docker rmi -f $(docker images | grep  "M*/$PRIMAGES" | grep "prod-2021*" | tail -n +3)
done

for QAIMAGES in ${pqimage}; do
docker images | grep  "M*/$QAIMAGES" | grep "qa-2021*" | tail -n +3 >> $log
sudo docker rmi -f $(docker images | grep  "M*/$QAIMAGES" | grep "qa-2021*" | tail -n +3)
done

错误

"docker rmi" requires at least 1 argument(s).
See 'docker rmi --help'.

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images
"docker rmi" requires at least 1 argument(s).
See 'docker rmi --help'.

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images
"docker rmi" requires at least 1 argument(s).
See 'docker rmi --help'.

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images
"docker rmi" requires at least 1 argument(s).
See 'docker rmi --help'.

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images
"docker rmi" requires at least 1 argument(s).
See 'docker rmi --help'.

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images
"docker rmi" requires at least 1 argument(s).```

删除之前检查是否有要删除的图像。另外,不要 运行 docker images 两次...只需使用变量。

for PRIMAGES in $pqimage; do
    tmp=$(docker images | grep  "M*/$PRIMAGES" | grep "prod-2021*" | tail -n +3)
    echo "$tmp" >> "$log"
    if [[ -n "$tmp" ]]; then
       sudo docker rmi -f $tmp
    fi
done

使用 http://shellcheck.net

检查您的脚本

不要使用反引号`。请改用 $(...)。

引用变量扩展。

缩进函数体。

不要对内部变量使用大写变量。在脚本中首选小写变量。

缓存 docker images 的结果。它不像它改变每个循环...

我想我会一起做点什么:

# One could use `tee`, but I think it's clearer with one temporary variable.
tmp=$(docker images | grep -f <(printf "M*/%s\n" $pqimage))
{
   <<<"$tmp" grep "prod-2021*" | tail -n +3 | tee >(cat >>"$log")
   <<<"$tmp" grep "qa-2021*"   | tail -n +3 | tee >(cat >>"$log")
} | xargs -d'\n' -r sudo docker rmi -f

或者您甚至可以使用单个 awk 在一个阶段进行解析。