macOS中du默认跳过隐藏目录且会因挂载点重复统计,需用du -shx或ncdu配合排除规则;日志文件可能被进程锁定导致du显示大小≠实际占用,应结合lsof排查deleted-but-held文件。

du命令在macOS里默认不递归扫描隐藏目录
MacOS的du默认跳过以.开头的目录(比如.logs、.cache),而系统日志和第三方应用日志常藏在这里。直接跑du -sh *完全看不到~/Library/Logs或/var/log下的真实体积。
必须显式指定路径,并加-a(列出所有文件)或确保通配符包含点文件:
-
du -sh ~/Library/Logs/**/* 2>/dev/null | sort -hr | head -20——**开启glob递归,2>/dev/null屏蔽权限拒绝错误 -
du -sh /var/log/* /var/log/.*/ 2>/dev/null | sort -hr | head -15—— 手动补上.*/匹配隐藏子目录 - 别用
du -sh .*,它只列当前层的隐藏项,不进子目录
避开/System/Volumes/Data这类挂载点导致的重复统计
macOS Catalina之后,系统分区被拆成只读的/System/Volumes/Data和可写的/,但du会把同一物理文件按不同挂载路径重复计算——比如/Users其实是/System/Volumes/Data/Users的符号链接,扫两次就翻倍。
实操时务必确认目标路径是否为真实挂载点:
- 先运行
df -h /path/to/dir,看输出的Filesystem列是否和根目录一致;若不同,说明是独立挂载点,需单独处理 - 对
/Users这类路径,直接查/System/Volumes/Data/Users更准,且避免跨卷重复 -
du -shx(小写x)可限制在同一文件系统内,跳过其他挂载点,适合快速排除干扰
日志文件常被进程锁定,du显示大小≠磁盘占用
像console.log、system.log这类活跃日志,可能被logd或syslogd持续写入,du读到的是当前文件大小,但实际磁盘空间未必立刻释放——尤其当日志轮转后旧文件被rm但句柄未关闭时,空间仍被占用。
验证真实磁盘压力得结合lsof:
- 查被删除但仍占空间的日志:
lsof +L1 | grep log(+L1表示link count=0的已删文件) - 看某日志是否被进程持有:
lsof -Pn +D /var/log | grep -E "(deleted|log)" - 单纯
du结果偏小?大概率有deleted-but-held文件,重启对应服务(如sudo launchctl kickstart -k system/com.apple.syslogd)才能释放
用ncdu替代du获得交互式定位体验
du输出是静态列表,找超大日志得靠sort和head拼接,效率低还容易漏层级。macOS上装ncdu(brew install ncdu)能直接钻进目录树,实时排序、展开、删除,对日志这种深嵌套结构更友好。
关键操作习惯:
- 启动时加
--exclude=".git"等无关目录,避免扫描干扰项 - 进目录后按
d可安全删除(会二次确认),比rm -rf直观得多 -
ncdu -x ~/Library/Logs加-x防止跨文件系统,和du -shx逻辑一致 - 注意
ncdu默认不统计硬链接重复内容,比du更接近真实占用
真正的难点不在命令怎么写,而在判断某个“大文件”是不是还在被服务引用——删了asl或unified日志前,最好先log show --last 1h确认近期有没有关键报错依赖它。

















