macOS 磁盘占用诊断与安全清理
第 0 步:先纠正概念
用户说"内存满了",99% 是磁盘空间不足,不是 RAM。先跑 df -h 确认,并明确告诉用户这个区别——因为"关软件"解决不了磁盘问题。
df -h / /System/Volumes/Data
diskutil apfs list | head -60 # 看各卷占用(Preboot/VM/Recovery 也要看)
diskutil info / | grep -i "Container Free Space"
tmutil listlocalsnapshots / # Time Machine 本地快照是常见的"空间黑洞"
本地快照过多是很多人"空间莫名消失"的真凶,务必先排除。
第 1 步:分层扫描(关键技巧)
绝对不要直接 du -sh ~/* —— 主目录文件数太多会被 SIGKILL(exit code 137),白等几分钟。
正确做法是分层、分目录、逐个扫,每层单独一次调用(可加 -x 限制不跨文件系统):
# 第一层:系统级
du -sh -x /Users/* /private/* /Library /usr /Applications /opt 2>/dev/null | sort -rh | head -15
# 第二层:用户 Library 的主要子目录
du -sh -x ~/Library/Caches ~/Library/Containers ~/Library/"Group Containers" \
~/Library/"Application Support" ~/Library/Logs ~/Library/Developer 2>/dev/null
# 第三层:可见目录(逐个,别用通配)
for d in Desktop Documents Downloads Movies Pictures Music; do
printf "%-12s " "$d"; du -sh -x ~/"$d" 2>/dev/null | cut -f1
done
# 第四层:隐藏缓存
du -sh -x ~/.Trash ~/.cache ~/.npm ~/.docker ~/.conda ~/.vscode ~/.workbuddy 2>/dev/null | sort -rh
继续往下拆时也用同样方式:du -sh -x "$DIR"/* | sort -rh | head -20。
收尾必做:各层加总要能和 df 的已用量对平。对不平才说明还有隐藏项,再针对性找。对平了就可以告诉用户"没有神秘黑洞"——这句话本身就是最大的价值。
第 2 步:国产 App 数据目录速查(真正的"看不见的地方")
这些 App 本体通常只有 1–2GB,但沙盒数据能到几十 GB,且访达默认不显示全路径。
微信 WeChat 4.x(最常见的第一大元凶)
~/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/<wxid>/msg/attach # 图片,通常最大
.../msg/video # 视频
.../db_storage # 聊天记录数据库
.../business # 小程序数据
.../msg/file # 传输文件
- 注意:旧版路径是
.../WeChat Files/,4.x 已改为容器内xwechat_files/ msg/attach下按会话哈希(32 位十六进制)命名,无年月结构- 取时间分布要逐个目录
stat -f "%Sm" -t "%Y-%m",不能靠目录名
企业微信 WeCom
~/Library/Containers/com.tencent.WeWorkMac/Data/Documents/cefcache/wew_<企业ID> # Chromium 缓存
.../Profiles/<32位hex>/Messages1/Session.db # ⚠️ 聊天记录主体
.../Profiles/<32位hex>/Publishsys/pkg # 前端资源包
.../Data/Library/Application Support/WXWork/Data/<企业ID>
飞书 Lark
~/Library/Application Support/LarkShell/aha/users/<账号ID>/profile_explorer/Service Worker/CacheStorage # 网页缓存,通常最大
~/Library/Application Support/LarkShell/update # 旧版本安装包
~/Library/Application Support/LarkShell/sdk_storage # SDK 本地状态(不是纯缓存)
~/Library/Caches/LarkShell
~/Library/Mobile Documents/iCloud~com~bytedance~ee~lark
WPS Office
~/Library/Containers/com.kingsoft.wpsoffice.mac/Data/Library/Application Support
卸载后的残留位置(通用清单)
~/Library/Application Support/<App>
~/Library/Caches/<bundle-id>*
~/Library/Preferences/<bundle-id>*.plist
~/Library/HTTPStorages/<bundle-id>
~/Library/Saved Application State/<bundle-id>.savedState
/private/var/folders/*/*/C/<bundle-id>* # 最容易漏!普通清理工具找不到
搜索残留用 bundle-id 关键字:
find ~/Library ~/private/var/folders/nz -maxdepth 3 \( -iname "*lark*" -o -iname "*feishu*" \) 2>/dev/null
第 3 步:风险分级(决定"能不能删")
永远不要把"软件数据"一刀切当成"缓存"。必须分级:
| 级别 | 判断依据 | 例子 |
|---|---|---|
| 🟢 纯缓存 | 在 Caches/ 下、Service Worker CacheStorage、ShaderCache、日志、旧版本安装包 |
可再生,删了无影响 |
| 🟡 依赖云端 | 数据在服务器,本地只是副本 | 个人微信/飞书的聊天记录 |
| 🔴 本地独有 | 本地 SQLite 数据库、离线标记文件、未同步草稿、本地会议录制 | 删了可能永久丢失 |
关键差异(务必区分,别搞混)
- 个人微信 / 飞书:聊天记录主体在服务器,本地大头是网页缓存 → 删缓存安全
- 企业微信:聊天记录主体在本地
Session.db,服务器仅按企业保留策略存部分 → 删了就没了
判断"删除代价"时必问:重新登录能不能取回来? 如果不能(比如已离职、账号被停用),本地就是唯一副本。
其他易丢项
- 输入框草稿、飞书"离线文件"标记的文件
- 本地搜索索引(删后需重建,短期搜不到历史)
Caches/Files这类"文件缓存"(重新下载需要账号still有效)
第 4 步:清理执行协议
移入废纸篓,不要 rm
# Finder 自动化在本机常被系统拒绝(-10004 privilege violation),别依赖 osascript
osascript -e 'tell application "Finder" to delete (POSIX file "/path" as alias)' # 可能失败
# 可行方案:mv 到 ~/.Trash 的自建子目录(同卷 rename,瞬间完成,不需要额外空间)
TRASH_DIR="$HOME/.Trash/清理备份_$(date +%Y%m%d)"
mkdir -p "$TRASH_DIR"
mv "$SRC" "$TRASH_DIR/<语义化名称>"
注意:
ls ~/.Trash可能被沙箱拒绝(Operation not permitted),靠mv返回码 + 目标存在性校验来判断成功- basename 会冲突(如
Caches/Adobe和Logs/Adobe),用自定义语义化目标名区分 - 同卷移动不释放空间,必须清空废纸篓才真正腾出——要主动告诉用户,否则用户会以为没生效
处理运行中的 App
- 先
pgrep -f "<AppName>"确认是否运行 - 运行中的 App:其缓存会被立刻重建,白费力气;WorkBuddy/编辑器类正在使用的缓存目录不要动(用
stat看 mtime 判断是否活跃) - 建议让用户先退出 App 再清理
执行前核验
# 检查待清理项是否存在、当前体积(体积会变,别用旧数据)
for p in <path1> <path2>; do
[ -e "$p" ] && printf "%-40s %s\n" "$(basename "$p")" "$(du -sh -x "$p" 2>/dev/null | cut -f1)"
done
执行后核验(必做)
- 源路径确实不存在
- 废纸篓备份区体积 = 预期
- 保留项完好(这一步最重要,别只检查删掉的)
第 5 步:交付
产出两份文件:
- 诊断报告:占用排行表 + 每项明细 + 分级清理建议(P0–P3 优先级 + 预计释放量 + 风险)
- 清理记录与还原指南:原路径 ↔ 废纸篓名称对照表(用户能自己还原)+ 空间变化表 + 各软件自我恢复行为
回答用户高频疑问
"删了 Homebrew / pip 缓存会不会变慢?" 不会。删的是下载缓存,不是已装软件。用实测数据回答:
ls -1 /opt/homebrew/Cellar | wc -l # 已装 formulae,应完好
/opt/homebrew/bin/brew --version
ls -1 /opt/homebrew/lib/python3*/site-packages | wc -l
唯一影响:下次 brew install / pip install 需重新下载。这正是官方 brew cleanup / pip cache purge 的常规操作。
"重装 App 后数据还在吗?" 取决于该 App 的数据归属(见第 3 步分级表),不能一概而论。
沟通原则
- 先给诊断结论,再给行动建议
- 用户说"先不要删"时严格只读扫描,一步都不动
- 每批清理后汇报:删了什么(具体路径+体积)、刻意跳过什么(及原因)、空间实际变化
- 刻意跳过高风险项并说明原因,比闷头删完更有价值