ubuntu 清理
#!/bin/bash
# =============================
# 合并版 Ubuntu 系统清理脚本(带进度和空间统计)
# 包含:
# - Conda 缓存清理(兼容旧版)
# - Pip 缓存清理
# - APT 缓存清理
# - 系统临时文件清理
# - 系统日志清理
# - Docker 垃圾清理
# - 旧内核清理
# - 用户缓存清理
# - 交互式菜单选择
# Date: 2025-07-18
# =============================
# ANSI 颜色代码
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'
# 日志函数
log() {
echo -e "${GREEN}[INFO] $1${NC}"
}
warn() {
echo -e "${YELLOW}[WARN] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
}
progress() {
echo -e "${BLUE}[PROGRESS] $1${NC}"
}
# 确认函数
confirm() {
read -p "$1 是否继续?(y/n): " -n 1 -r
echo
[[ $REPLY =~ ^[Yy]$ ]]
}
# 清屏函数
clear_screen() {
clear
}
# 获取目录大小(MB)
get_size() {
if [ -d "$1" ]; then
du -sm "$1" 2>/dev/null | awk '{print $1}'
else
echo 0
fi
}
# 获取文件大小(MB)
get_file_size() {
if [ -e "$1" ]; then
du -sm "$1" 2>/dev/null | awk '{print $1}'
else
echo 0
fi
}
# 格式化数字为千分位
format_number() {
echo $1 | awk '{ printf "%\047d\n", $1 }'
}
# 主菜单
main_menu() {
clear_screen
echo "=========================================="
echo " Ubuntu 系统清理工具"
echo "=========================================="
echo "1) 清理 Conda 缓存(兼容旧版)"
echo "2) 清理 pip 缓存"
echo "3) 清理 APT 缓存"
echo "4) 清理系统临时文件(/tmp)"
echo "5) 清理用户缓存(~/.cache)"
echo "6) 清理系统日志"
echo "7) 删除无用依赖"
echo "8) 删除旧内核(谨慎操作)"
echo "9) 清理 Docker 垃圾(images, containers, volumes, networks)"
echo "10) 执行所有清理任务"
echo "q) 退出"
echo
read -p "请选择要执行的操作: " choice
case $choice in
1) cleanup_conda ;;
2) cleanup_pip ;;
3) cleanup_apt ;;
4) cleanup_tmp ;;
5) cleanup_user_cache ;;
6) cleanup_logs ;;
7) remove_unused_deps ;;
8) remove_old_kernels ;;
9) cleanup_docker ;;
10) run_all ;;
q|Q) exit 0 ;;
*) error "无效选项,请重新选择。"; sleep 2 ;;
esac
}
# 显示清理前预估空间
show_pre_cleanup_stats() {
local target="$1"
case "$target" in
"conda")
if command -v conda &>/dev/null; then
local conda_pkgs_size=$(get_size ~/anaconda3/pkgs)
local conda_cache_size=$(get_size ~/anaconda3/conda-meta/package_cache)
total_size=$((conda_pkgs_size + conda_cache_size))
echo "预计可清理 Conda 缓存大小: ${total_size}MB"
else
warn "未检测到 Conda"
fi
;;
"pip")
if command -v pip &>/dev/null; then
local pip_cache_size=$(get_size ~/.cache/pip)
echo "预计可清理 pip 缓存大小: ${pip_cache_size}MB"
else
warn "未检测到 pip"
fi
;;
"apt")
local apt_cache_size=$(get_size /var/cache/apt/archives)
echo "预计可清理 APT 缓存大小: ${apt_cache_size}MB"
;;
"tmp")
local tmp_size=$(get_size /tmp)
echo "预计可清理 /tmp 文件大小: ${tmp_size}MB"
;;
"user_cache")
local user_cache_size=$(get_size ~/.cache)
echo "预计可清理用户缓存大小: ${user_cache_size}MB"
;;
"logs")
local log_size=$(get_size /var/log)
echo "预计可清理日志文件大小: ${log_size}MB"
;;
"unused_deps")
echo "预计可清理无用依赖: 50-200MB(视系统情况而定)"
;;
"old_kernels")
local old_kernels_size=$(dpkg --list | grep -i linux-image | awk '{ print $2 }' | grep -v "$(uname -r)" | grep -v "generic" | wc -l)
if [ "$old_kernels_size" -gt 0 ]; then
echo "检测到 $old_kernels_size 个旧内核(每个约 100-300MB)"
else
echo "未检测到旧内核"
fi
;;
"docker")
if command -v docker &>/dev/null; then
local docker_size=$(docker system df | grep "Total" | awk '{print $3}' | sed 's/[A-Za-z]//g')
echo "预计可清理 Docker 垃圾大小: ${docker_size}MB"
else
warn "未检测到 Docker"
fi
;;
"all")
show_pre_cleanup_stats "conda"
show_pre_cleanup_stats "pip"
show_pre_cleanup_stats "apt"
show_pre_cleanup_stats "tmp"
show_pre_cleanup_stats "user_cache"
show_pre_cleanup_stats "logs"
show_pre_cleanup_stats "docker"
show_pre_cleanup_stats "old_kernels"
;;
esac
}
# 清理 Conda 缓存(兼容旧版)
cleanup_conda() {
log "开始清理 Conda 缓存..."
if command -v conda &> /dev/null; then
local before_size=$(($(get_size ~/anaconda3/pkgs) + $(get_size ~/anaconda3/conda-meta/package_cache)))
progress "清理 Conda 缓存(tarball、索引缓存、日志等)..."
conda clean --tarballs --index-cache --logs -y
progress "清理未安装但缓存的包..."
if [ -d ~/anaconda3/pkgs ]; then
find ~/anaconda3/pkgs -type f -name "*.tar.bz2" -delete
else
warn "未找到 Conda 的 pkgs 目录"
fi
local after_size=$(($(get_size ~/anaconda3/pkgs) + $(get_size ~/anaconda3/conda-meta/package_cache)))
local saved=$((before_size - after_size))
log "Conda 缓存清理完成,共释放空间: ${saved}MB"
log "列出所有 Conda 环境(你可以手动删除不需要的环境):"
conda env list
else
warn "未检测到 Conda,跳过清理"
fi
}
# 清理 pip 缓存
cleanup_pip() {
log "开始清理 pip 缓存..."
if command -v pip &> /dev/null; then
local before_size=$(get_size ~/.cache/pip)
progress "清理 pip 缓存..."
if pip cache purge 2>/dev/null; then
log "pip 缓存清理完成"
else
progress "使用传统方式清理 pip 缓存..."
pip cache remove --all
fi
local after_size=$(get_size ~/.cache/pip)
local saved=$((before_size - after_size))
log "pip 缓存清理完成,共释放空间: ${saved}MB"
else
warn "未检测到 pip,跳过清理"
fi
}
# 清理 APT 缓存
cleanup_apt() {
log "开始清理 APT 缓存..."
if confirm "确定要清理 APT 缓存吗?这将删除 /var/cache/apt/archives 中的所有 .deb 文件"; then
local before_size=$(get_size /var/cache/apt/archives)
sudo apt-get clean
sudo apt-get autoclean
local after_size=$(get_size /var/cache/apt/archives)
local saved=$((before_size - after_size))
log "APT 缓存清理完成,共释放空间: ${saved}MB"
fi
}
# 清理系统临时文件
cleanup_tmp() {
log "开始清理 /tmp 文件..."
if confirm "确定要删除 /tmp 中超过 7 天的文件吗?"; then
local before_size=$(get_size /tmp)
sudo find /tmp -mindepth 1 -mtime +7 -exec rm -rf {} +
local after_size=$(get_size /tmp)
local saved=$((before_size - after_size))
log "/tmp 文件清理完成,共释放空间: ${saved}MB"
fi
}
# 清理用户缓存
cleanup_user_cache() {
log "开始清理用户缓存 ~/.cache ..."
if confirm "确定要删除 ~/.cache 中超过 7 天的文件吗?"; then
local before_size=$(get_size ~/.cache)
find ~/.cache -type f -mtime +7 -delete
local after_size=$(get_size ~/.cache)
local saved=$((before_size - after_size))
log "用户缓存清理完成(保留最近 7 天内的),共释放空间: ${saved}MB"
fi
}
# 清理系统日志
cleanup_logs() {
log "开始清理系统日志..."
if confirm "是否清理 /var/log 中的旧日志文件?"; then
local before_size=$(get_size /var/log)
sudo journalctl --vacuum-time=7d
sudo find /var/log -type f -name "*.log.*" -delete 2>/dev/null
sudo rm -f /var/log/*.gz /var/log/*.old /var/log/*.1 /var/log/syslog.1
local after_size=$(get_size /var/log)
local saved=$((before_size - after_size))
log "系统日志清理完成,共释放空间: ${saved}MB"
fi
}
# 删除无用依赖
remove_unused_deps() {
log "开始删除无用依赖..."
if confirm "确定要删除无用依赖吗?"; then
local before_size=50 # 估计值
sudo apt-get autoremove --yes
log "无用依赖清理完成,预计释放空间: 50-200MB"
fi
}
# 删除旧内核
remove_old_kernels() {
log "开始查找可以删除的旧内核..."
# 获取当前运行的内核版本
current_kernel=$(uname -r)
# 列出所有已安装的内核包
old_kernels=$(dpkg --list | grep -i linux-image | awk '{ print $2 }' | grep -v "$current_kernel" | grep -v "generic")
if [ -z "$old_kernels" ]; then
warn "没有发现可删除的旧内核。"
return
fi
echo "以下内核将被删除:"
echo "$old_kernels"
if confirm "是否继续删除这些旧内核?请确保保留至少一个备用内核"; then
local before_count=$(echo "$old_kernels" | wc -l)
local estimated_saved=$((before_count * 200))
log "预计将删除 $before_count 个旧内核,共释放空间: ${estimated_saved}MB"
log "正在进行内核清理,请稍候..."
sudo apt purge $old_kernels
sudo apt autoremove --purge
log "旧内核清理完成,预计释放空间: ${estimated_saved}MB"
fi
}
# 清理 Docker 垃圾
cleanup_docker() {
log "开始清理 Docker 垃圾..."
if command -v docker &>/dev/null; then
local docker_size=$(docker system df | grep "Total" | awk '{print $3}' | sed 's/[A-Za-z]//g')
if confirm "是否删除无用的 Docker 镜像、容器、卷和网络?"; then
log "预计清理 Docker 垃圾大小: ${docker_size}MB"
log "正在进行 Docker 垃圾清理,请稍候..."
docker system prune -af
docker volume prune -f
log "Docker 垃圾清理完成"
fi
else
warn "未检测到 Docker,跳过该步骤"
fi
}
# 执行所有清理任务
run_all() {
log "开始执行全部清理任务..."
# 显示预估清理空间
log "📊 预计清理空间概览:"
show_pre_cleanup_stats "all"
echo
if confirm "是否继续执行全部清理任务?"; then
cleanup_conda
cleanup_pip
cleanup_apt
cleanup_tmp
cleanup_user_cache
cleanup_logs
cleanup_docker
remove_unused_deps
if confirm "是否也要清理旧内核?(谨慎操作)"; then
remove_old_kernels
fi
log "所有清理任务已完成。建议重启系统以释放更多空间(特别是删除旧内核后)。"
fi
}
# 主程序入口
while true; do
main_menu
done