本文目录导读:

这是一个自动清理 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
使用方法
-
保存脚本
# 保存为 cargo-cache-clean.sh chmod +x cargo-cache-clean.sh
-
常用命令
# 预览可清理的内容(安全模式) ./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 上都能正常工作。