df -h 用于查看各挂载点磁盘使用情况,重点关注 use% 列;du -sh 用于统计指定目录实际占用空间;二者结果差异通常源于已删除未释放文件、挂载覆盖或元数据占用。

df -h 看的是文件系统整体剩多少
你真正想问的,其实是“我的磁盘快满了,到底哪块盘顶不住了”——df 就是干这个的。它不看文件,只看挂载点背后的整块分区用了多少、还剩多少。
-
df -h是必须加的选项,否则显示 KB 单位的数字(比如81120644),人眼根本没法判断是 80GB 还是 80MB - 重点关注
Use%列,但别只盯着/;有些系统把/boot/efi或/var/log单独挂载,它们可能先爆满 - 看到
tmpfs行(如/run、/dev/shm)直接跳过——那是内存模拟的临时文件系统,重启就清空,和磁盘无关 - 如果某挂载点明明还有空间却写不进文件,立刻跑
df -i:可能是 inode 耗尽,不是空间不够
du -sh /path 看的是目录实际占了多少空间
df 告诉你“路宽不宽”,du 告诉你“路上堆了多少货”。比如 df 显示 / 还剩 20GB,但 du -sh /var/log 一查发现占了 18GB,问题立马定位。
-
du -sh是最常用组合:-s表示只汇总、不展开子目录;-h让结果可读(3.2G比3355443直观得多) - 慎用
du /(不加路径)——它会遍历整个根文件系统,耗时长、IO 高,生产环境可能拖慢服务 - 注意硬链接:
du默认按实际占用块计算,一个 4KB 文件即使有 10 个硬链接,也只算一次 4KB;而ls -l显示的大小是逻辑大小,两者可能不一致 - 如果你发现
du总和远小于df的已用空间,大概率是有进程删了大文件但没释放句柄(lsof +L1可查)
df 和 du 结果对不上?八成是这三种情况
这是最常被问“为什么”的地方。两个命令原理不同,结果天然可能不等,但差距过大就该排查了。
- 已删除但未关闭的文件:进程还在写一个已被
rm的日志,df认为它占空间,du找不到路径所以不统计——用lsof | grep deleted确认 - 挂载覆盖:比如你在
/mnt/data挂了一块盘,又在它下面建了/mnt/data/app/logs并挂了另一块盘,du会递归进去统计,但df只认最外层挂载点 - ACL 或扩展属性(xattr):极少数情况下,文件系统元数据本身占空间,
du不计入,df会计入
快速定位大目录的实用命令组合
光知道“哪个目录大”还不够,得能快速翻出前几名——靠手动 du -sh * 太慢,也容易漏隐藏目录。
- 查当前目录下最大的 10 个子目录:
du -sh .[!.]* * 2>/dev/null | sort -hr | head -n 10(.[!.]*匹配以点开头的隐藏目录,2>/dev/null屏蔽权限错误) - 排除特定路径(比如跳过容器镜像):
du -sh --exclude=/var/lib/docker /var/* 2>/dev/null | sort -hr | head -5 - 想实时监控变化?
watch -n 30 'du -sh /var/log'每 30 秒刷新一次,比反复敲命令省心
真正卡住系统的,往往不是“总空间不足”,而是某个小分区(比如 /boot)或某个日志目录悄悄吃光了所有 inode 或空间。别只信 df -h 的第一行,多看一眼挂载点列表,再用 du -sh 往深里挖一层——这才是运维现场的真实节奏。










