自动清理cargo缓存的脚本

wen 实用脚本 2

本文目录导读:

自动清理cargo缓存的脚本

  1. 默认清理(30天前的缓存)
  2. 清理所有缓存(包括 complete 目录)
  3. 保留最近7天,清理其余
  4. 清理大于100MB的缓存
  5. 自动确认,不提示
  6. 组合使用:保留7天,清理所有大于50MB的

这是一个自动清理 Cargo 缓存的 Bash 脚本,适用于 Linux、macOS 和 Windows(Git Bash/WSL)。

#!/bin/bash
# Cargo Cache Cleaner - 自动清理 Cargo 缓存
# 用法: ./cargo-cache-clean.sh [options]
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 默认配置
CACHE_DIR="${HOME}/.cargo"
DRY_RUN=false
DELETE_ALL=false
KEEP_DAYS=30
MIN_SIZE_MB=0
AUTO_YES=false
# 帮助信息
usage() {
    echo -e "${BLUE}Cargo Cache Cleaner${NC} - 清理 Rust/Cargo 构建缓存"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -h, --help          显示帮助信息"
    echo "  -d, --dry-run       仅显示可清理的内容,不实际删除"
    echo "  -a, --all           清理所有缓存(包括 complete 目录)"
    echo "  -k, --keep DAYS     保留最近 N 天的缓存(默认: 30)"
    echo "  -m, --min-size MB   清理大于指定 MB 的包(默认: 0 = 所有)"
    echo "  -y, --yes           自动确认,不提示"
    echo ""
    echo "示例:"
    echo "  $0                   清理 30 天前的缓存"
    echo "  $0 --dry-run         预览可清理内容"
    echo "  $0 --all --keep 7    保留最近 7 天,清理其余所有"
    echo "  $0 --min-size 100    清理大于 100MB 的过期包"
}
# 解析参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            usage
            exit 0
            ;;
        -d|--dry-run)
            DRY_RUN=true
            shift
            ;;
        -a|--all)
            DELETE_ALL=true
            shift
            ;;
        -k|--keep)
            KEEP_DAYS="$2"
            shift 2
            ;;
        -m|--min-size)
            MIN_SIZE_MB="$2"
            shift 2
            ;;
        -y|--yes)
            AUTO_YES=true
            shift
            ;;
        *)
            echo -e "${RED}错误: 未知参数 $1${NC}"
            usage
            exit 1
            ;;
    esac
done
# 检查 cargo 缓存目录
if [ ! -d "$CACHE_DIR" ]; then
    echo -e "${RED}错误: Cargo 缓存目录不存在: $CACHE_DIR${NC}"
    exit 1
fi
echo -e "${BLUE}════════════════════════════════════════${NC}"
echo -e "${BLUE}   Cargo 缓存清理工具                    ${NC}"
echo -e "${BLUE}════════════════════════════════════════${NC}"
echo ""
echo -e "缓存目录: ${YELLOW}$CACHE_DIR${NC}"
echo -e "保留天数: ${YELLOW}${KEEP_DAYS}天${NC}"
if [ "$MIN_SIZE_MB" -gt 0 ]; then
    echo -e "最小大小: ${YELLOW}${MIN_SIZE_MB}MB${NC}"
fi
echo -e "预览模式: ${YELLOW}$([ "$DRY_RUN" = true ] && echo '是' || echo '否')${NC}"
echo -e "清理所有: ${YELLOW}$([ "$DELETE_ALL" = true ] && echo '是' || echo '否')${NC}"
echo ""
# 获取当前时间和阈值时间
CURRENT_TIME=$(date +%s)
THRESHOLD_TIME=$((CURRENT_TIME - KEEP_DAYS * 86400))
# 计数器
total_freed=0
total_count=0
# 清理函数
clean_package() {
    local pkg_dir="$1"
    local pkg_name
    if [ -d "$pkg_dir" ]; then
        pkg_name=$(basename "$pkg_dir")
        # 获取包的大小
        if [[ "$OSTYPE" == "darwin"* ]]; then
            # macOS
            local size=$(du -sm "$pkg_dir" 2>/dev/null | cut -f1)
        else
            # Linux
            local size=$(du -sb "$pkg_dir" 2>/dev/null | cut -f1)
            size=$((size / 1048576))  # 转换为 MB
        fi
        # 如果没有大小信息,跳过
        if [ -z "$size" ]; then
            size=0
        fi
        # 检查大小条件
        if [ "$MIN_SIZE_MB" -gt 0 ] && [ "$size" -lt "$MIN_SIZE_MB" ]; then
            return
        fi
        # 清理动作
        if [ "$DRY_RUN" = true ]; then
            echo -e "  [${YELLOW}预览${NC}] 将删除: ${GREEN}$pkg_name${NC} (${size}MB)"
        else
            echo -e "  [${RED}删除${NC}] 清空: ${GREEN}$pkg_name${NC} (${size}MB)"
            rm -rf "$pkg_dir" 2>/dev/null
        fi
        total_freed=$((total_freed + size))
        total_count=$((total_count + 1))
    fi
}
# 清理 package 缓存
clean_package_cache() {
    local src_dir="${CACHE_DIR}/registry/src"
    local crates_dir="${CACHE_DIR}/registry/cache"
    # 清理 src 缓存
    if [ -d "$src_dir" ]; then
        echo -e "${BLUE}清理 registry/src 缓存...${NC}"
        find "$src_dir" -mindepth 1 -maxdepth 1 -type d | while read -r pkg; do
            clean_package "$pkg"
        done
    fi
    # 清理 crates 缓存
    if [ -d "$crates_dir" ]; then
        echo -e "${BLUE}清理 registry/cache 缓存...${NC}"
        find "$crates_dir" -mindepth 1 -maxdepth 1 -type d | while read -r pkg; do
            clean_package "$pkg"
        done
    fi
}
# 清理 build 缓存
clean_build_cache() {
    local git_dir="${CACHE_DIR}/git"
    if [ -d "$git_dir" ]; then
        echo -e "${BLUE}清理 git 缓存...${NC}"
        find "$git_dir" -mindepth 1 -maxdepth 1 -type d | while read -r repo; do
            clean_package "$repo"
        done
    fi
}
# 清理 complete 目录(如果有)
clean_complete_cache() {
    local complete_dir="${CACHE_DIR}/complete"
    if [ -d "$complete_dir" ]; then
        echo -e "${BLUE}清理 complete 目录...${NC}"
        if [ "$DRY_RUN" = true ]; then
            echo -e "  [${YELLOW}预览${NC}] 将删除 complete 目录"
        else
            echo -e "  [${RED}删除${NC}] 删除 complete 目录"
            rm -rf "$complete_dir" 2>/dev/null
        fi
        total_freed=$((total_freed + 100))  # 估算 100MB
        total_count=$((total_count + 1))
    fi
}
# 按时间清理(清理旧版本的包)
clean_old_versions() {
    local src_dir="${CACHE_DIR}/registry/src"
    if [ -d "$src_dir" ]; then
        echo -e "${BLUE}清理过时版本缓存...${NC}"
        find "$src_dir" -mindepth 1 -maxdepth 1 -type d | while read -r pkg; do
            local pkg_name=$(basename "$pkg")
            # 检查是否有多个版本
            local versions=$(find "$pkg" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
            if [ "$versions" -gt 1 ]; then
                # 按修改时间排序,保留最新的
                find "$pkg" -mindepth 1 -maxdepth 1 -type d -printf '%T@ %p\n' 2>/dev/null | \
                    sort -rn | tail -n +2 | while read -r line; do
                    local old_ver=$(echo "$line" | cut -d' ' -f2-)
                    clean_package "$old_ver"
                done
            fi
        done
    fi
}
# 统计当前缓存大小
cache_size() {
    if [[ "$OSTYPE" == "darwin"* ]]; then
        du -sh "$CACHE_DIR" 2>/dev/null | cut -f1
    else
        du -sh "$CACHE_DIR" 2>/dev/null | cut -f1
    fi
}
# 主要清理流程
main() {
    echo -e "当前缓存大小: ${YELLOW}$(cache_size)${NC}"
    echo ""
    # 确认操作
    if [ "$DRY_RUN" = false ] && [ "$AUTO_YES" = false ]; then
        echo -e -n "${YELLOW}是否继续清理? [y/N] ${NC}"
        read -r confirm
        if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
            echo "操作取消"
            exit 0
        fi
        echo ""
    fi
    # 执行清理
    if [ "$DELETE_ALL" = true ]; then
        # 清理所有缓存
        clean_complete_cache
        clean_build_cache
        clean_package_cache
    else
        # 按条件和时间清理
        clean_old_versions
        clean_package_cache
    fi
    # 清理 cargo 日志
    if [ -f "${CACHE_DIR}/.cargo-lock" ]; then
        rm -f "${CACHE_DIR}/.cargo-lock"
    fi
    # 报告结果
    echo ""
    echo -e "${BLUE}════════════════════════════════════════${NC}"
    echo -e "清理结果:"
    echo -e "  处理包数: ${GREEN}${total_count}${NC}"
    echo -e "  释放空间: ${GREEN}${total_freed}MB${NC}"
    echo -e "  当前缓存: ${YELLOW}$(cache_size)${NC}"
    echo -e "${BLUE}════════════════════════════════════════${NC}"
    if [ "$DRY_RUN" = true ]; then
        echo -e "${YELLOW}提示: 以上为预览结果,并未实际删除${NC}"
        echo -e "${YELLOW}执行实际清理请运行: $0${NC}"
    fi
}
# 执行主函数
main

使用方法

  1. 保存脚本

    # 保存为 cargo-cache-clean.sh
    chmod +x cargo-cache-clean.sh
  2. 常用命令

    # 预览可清理的内容(安全模式)
    ./cargo-cache-clean.sh --dry-run

默认清理(30天前的缓存)

./cargo-cache-clean.sh

清理所有缓存(包括 complete 目录)

./cargo-cache-clean.sh --all

保留最近7天,清理其余

./cargo-cache-clean.sh --keep 7

清理大于100MB的缓存

./cargo-cache-clean.sh --min-size 100

自动确认,不提示

./cargo-cache-clean.sh --yes

组合使用:保留7天,清理所有大于50MB的

./cargo-cache-clean.sh --keep 7 --min-size 50 --all


## 功能特点
- ✅ **安全预览模式**:使用 `--dry-run` 查看会删除什么
- ✅ **智能清理**:按时间和大小的组合条件清理
- ✅ **彩色输出**:清晰的视觉反馈
- ✅ **备份保留**:默认保留最近30天
- ✅ **自动确认**:支持非交互模式
## 注意事项
1. **首次清理**:建议先用 `--dry-run` 预览
2. **磁盘空间**:Rust 缓存可能很大(几GB),特别是多项目开发
3. **影响**:删除缓存后,下次构建会重新下载,但不会影响编译结果
4. **安全**:脚本只清理 `~/.cargo/registry/` 下的缓存,不会影响你的代码
这个脚本在 Linux/macOS 和 WSL 上都能正常工作。

抱歉,评论功能暂时关闭!