Linux du 命令:查看目录占用、查找大文件与比较 df

du 用于估算文件和目录在文件系统中占用的空间。查看当前目录及下一层子目录的汇总,可用 du -h --max-depth=1 .;只看当前目录总量,可用 du -sh .。命令最后的点表示当前目录,前面应保留空格。

du -h --max-depth=1 .
du -sh .

默认统计依据是操作系统报告的已分配块,而不是文件内容的逻辑长度。稀疏文件、压缩、硬链接及写时复制(Copy-on-Write,CoW)共享块,都可能让结果与其他工具或底层设备的真实占用不同。

du 计算什么?

du 是 disk usage 的缩写。它遍历指定的文件与目录树并汇总用量,结果受文件系统分配方式影响,不一定等于 ls -l 显示的文件长度,也不表示磁盘还剩多少空间。

本文按 GNU Coreutils 的 du 说明。完整选项和限制见 GNU Coreutils 官方文档源文件中的 du invocation 节。BusyBox、BSD 或旧版本支持的选项可能不同,先用 du --help 和本机手册核对。

最常用的基本命令

查看当前目录总量

du -sh .

-s 只显示每个命令行参数的汇总,-h 采用 1024 为基数的易读单位,通常以 K、M、G 等后缀显示。直接指定目录本身,会将可访问的隐藏文件与隐藏目录纳入统计。

把点替换为实际路径即可调查其他目录;路径中有空格时要加引号。du 是只读统计,不会自动删除文件、清理缓存或释放空间。

查看下一层子目录汇总

du -h --max-depth=1 .

起点为深度 0,--max-depth=1 显示起点和下一层子目录。默认不把每个普通文件单独列出来,需要同时显示文件时可加 -a。GNU du 也支持简写 -d 1。

深度选项限制的是输出,不是扫描深度。为了算出每个子目录总量,du 仍须遍历更深层的可访问内容;因此它不会保证磁盘 I/O 随输出减少而大幅下降。

按大小排序

du -h --max-depth=1 /var | sort -h

GNU sort -h 能识别 du -h 输出的单位并按升序排列。需要大项在前,使用反向排序:

du -h --max-depth=1 /var | sort -hr

/var 是示例起点,应改成实际需要调查的目录。结果包括 /var 自己的汇总行,不能把它与各子目录再次相加。权限不足会导致错误和不完整统计;管道最后的 sort 成功,也不证明上游 du 完整成功,应同时检查错误和退出状态。

主要选项

选项 作用 例子
-h 使用易读单位 du -h /var/log
-s 只显示每个参数的汇总 du -sh /var/log
-a 同时显示普通文件 du -ah ./data
-c 最后增加所有参数的合计 du -ch file1 file2
-d N 限制显示深度 du -h -d 2 .
-x 跳过其他文件系统 du -xhd1 /
--exclude 排除匹配的文件或目录 du -sh --exclude='*.log' .
--apparent-size 改看逻辑长度 du -sh --apparent-size file

进一步定位大目录与文件

列出文件并筛选较大的记录

du -ah ./data | sort -hr | head -n 20

先准备实际存在且可读取的 ./data 目录。-a 把文件也列出来,按大小降序后取前 20 行;这些行同时包含目录汇总与文件,不能称为“最大的 20 个文件”,也不能直接累加成唯一用量。

大目录中,du 需要遍历整个范围,sort 通常要处理全部输入后才能给出最终排序;head 不会让前面的扫描只检查 20 个文件。应缩小起点,避开业务高峰,并按相关子目录逐步调查。

只显示达到阈值的条目

du -h --threshold=1G ./data

正数 --threshold=1G 只输出大小大于或等于 1 GiB 的条目。这里默认输出目录;普通文件需配合 -a。阈值按当前统计模式判断,默认是块占用,使用 apparent-size 时改按逻辑大小。它同样只是输出过滤,不会保证省去扫描。

排除文件与目录

du -sh --exclude='*.log' --exclude='cache' .

单引号让星号先交给 du 的排除规则处理,而非由 shell 展开。这里排除 .log 文件以及匹配 cache 的目录或文件,汇总自然不再包含这些内容;不能与未排除的完整总量混为一谈。

规则较多时,先创建 du-exclude.txt,每行一个模式,例如分别写 *.log 与 cache,再运行:

du -sh --exclude-from=du-exclude.txt .

规则文件本身若也位于统计目录内且未被排除,仍可能计入用量。排除规则是文件名模式,不是用来匹配日志内容的正则表达式。

块占用与 apparent size 的区别

默认的磁盘用量

默认 du 汇总文件系统向操作系统报告的已分配空间。一个很小的文件可能占用一个分配块,也可能由文件系统的内联存储等机制处理;不能把“每个小文件至少固定占 4 KiB”当成通用规律。

文件系统元数据、冗余、快照及设备内部管理空间不一定完整反映在逐文件统计中,因此它不是物理设备占用的精确计量器。

逻辑长度

--apparent-size 对普通文件报告逻辑内容长度,配合 -h 转为易读单位。选择一个已有的 sample.img,可分别比较:

du -h sample.img
du -h --apparent-size sample.img

稀疏文件允许逻辑长度很大、实际分配较少;相反,小文件的块分配也可能大于逻辑长度。在压缩、去重、快照或 CoW 共享块环境中,默认 du 也不一定等于底层设备实际消耗,更不能用它直接预测删除后可释放多少空间。

硬链接的计数

多个硬链接可指向同一个 inode,即同一个文件对象。GNU du 默认在一次调用中只计算一次,命令行参数的先后顺序可能影响用量归属。-l 或 --count-links 可重复计入各链接,但合计可能超过唯一数据块用量。

分别执行多个 du 命令,会各自重新计数;不要把独立扫描中的共享文件用量不加区分地相加。硬链接也不同于符号链接,后者保存的是目标路径。

限制文件系统边界

跳过其他文件系统

调查根文件系统时,可用 -x 或 --one-file-system:

du -xhd1 /

这会跳过与起点属于不同文件系统的目录,减少误入其他数据卷、网络文件系统或虚拟文件系统的机会。但它不是“跳过所有挂载点”:同一文件系统的绑定挂载等仍需核对。被排除的文件系统用量当然不会出现在汇总中。

符号链接的处理

GNU du 默认不跟随符号链接的目标,包括命令行参数中的链接。-H 或 -D 跟随命令行指定的链接,-L 跟随遍历中遇到的链接;这些选项可能扩大范围或改变计数,应先确认目录结构与目的。

为什么 du 与 df 不一致?

统计对象不同

du 汇总当前可访问目录树中的文件,英文 df 命令说明介绍的 df 则读取文件系统整体空间统计。文件系统元数据、快照、被其他挂载覆盖的目录以及权限导致的遗漏,都可能造成差异。保留块还会影响 df 中普通用户可用空间,不应把它等同于文件内容占用。

已删除但仍打开的文件

最后一个目录链接被删除后,若进程仍持有该文件,du 可能已无法通过路径找到它,而文件空间仍可能被占用,df 也会反映相关用量。安装并支持对应功能的 lsof 可以查询:

lsof +L1

lsof 官方手册说明,+L1 选择链接计数小于 1 的已打开文件。可见范围受权限和实现影响,没有输出并不证明没有此类占用。

不要只为了释放空间就强制结束进程、随意截断文件描述符或改动 /proc 下的对象。应先确认文件所属服务,再按该服务支持的日志重新打开或正常维护流程处理;快照及其他引用也可能使空间不能立即全部释放。

安全、准确的排查顺序

  1. 先用 df -h 确认哪一个文件系统接近满,再选择该挂载点内的相关目录。
  2. 决定是否用 -x 排除其他文件系统,同时核对挂载覆盖和统计范围。
  3. 先输出较浅层的汇总,再对较大的子目录细查;记住浅层显示仍需遍历后代。
  4. 保留并检查权限及读取错误,记录不完整范围;只使用完成调查所需的权限。
  5. 若考虑删除内容,先确认所属服务、备份、保留政策和可恢复性,不凭排行直接删除。
  6. 自动化处理特殊文件名时,选择支持 NUL(空字符)分隔的配套工具;普通按行切割不适合含换行符的文件名。

扫描不是文件系统的原子快照。写入、轮转或文件删除发生在扫描期间时,结果会变化;比较两次结果应采用一致的路径、选项、权限和时间条件。

常见问答

隐藏文件会计入 du 吗?

直接指定目录,例如 du -sh .,会计入可访问的隐藏项。常见 shell 默认的星号不匹配点开头的名称,因此 du -sh * 可能遗漏;实际还取决于 shell 的通配设置。

怎样逐步找到最大的目录?

使用 du -h --max-depth=1 路径 | sort -hr 先看子目录汇总,再缩小到较大的目录。这样减少输出和排序记录,但不会让 du 自动跳过更深层扫描。

为什么 du -sh 与 ls -lh 的大小不同?

对普通文件,ls -lh 主要显示逻辑长度,默认 du 显示已分配块;稀疏文件、分配块和压缩等机制会使两者不同。对目录,ls -lh 的那一行也不是后代文件总量。

可以隐藏 Permission denied 吗?

隐藏错误不会补齐遗漏。应先确认报错路径和权限需求;若结果将用于容量判断,就应记录哪些目录未能读取,而不是把不完整合计当成准确总量。

使用要点

du -sh 路径 查看汇总,du -h --max-depth=1 路径 查看下一层子目录汇总,sort -hr 把较大记录排在前面。需要限制文件系统范围时用 -x,比较逻辑长度时用 apparent-size。若与 df 不一致,再检查统计范围、已删除的打开文件、权限与文件系统特性。