ubuntu 清理脚本

ubuntu 清理

bash 复制代码
#!/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
相关推荐
痕忆丶几秒前
openharmony开发之磁盘相关
linux
2601_954706491 分钟前
2026 上半年云手机实测:红手指 / 傲晨云 / ACE / 易舜云横向对比
运维·服务器·智能手机
z202305082 分钟前
RDMA 之RoCEv2 的报文格式(5)
linux·服务器·网络·人工智能
银河麒麟操作系统3 分钟前
【银河麒麟高级服务器操作系统】top命令详解
运维·服务器
uesowys4 分钟前
CentOS Linux安装部署Hermes Agent智能体
linux·centos·hermes agent
毋语天6 分钟前
Linux 命令——文件、进程、网络与 Vim 编辑器
linux·网络·编辑器
William.csj8 分钟前
Linux——查看cuda版本的全面方法
linux·运维·服务器
薛定猫AI2 小时前
Codex 与 Claude Code 全平台安装配置指南(Windows / macOS / Linux)
linux·windows·macos
仙柒4155 小时前
Docker原理
运维·docker·容器
米高梅狮子10 小时前
第2章 docker容器
运维·docker·云原生·容器·架构·kubernetes·自动化