阅读信息
- 内容类型:教程
- 难度:入门
- 适合谁:希望在 Linux、WSL2 与远程服务器上提升命令行效率的开发者。
- 读完后:用 dust 分析项目构建目录、日志目录与文件系统热点,并避免权限、挂载点和 WSL 跨盘扫描造成误判。
- 依据版本:dust 1.2.5
- 验证日期:2026-09-11
当服务器或本地开发机报出 No space left on device 时,df -h 只能告诉你“哪一个挂载点满了”,却无法展示空间究竟被埋在深层目录的哪个角落。
在传统 Linux 工作流中,排查磁盘热点往往需要繁琐地组合管道命令:
du -h --max-depth=1 /path | sort -hr | head -n 20这种方式不仅打字成本高,且每次深入下一层子目录都要重新拼接命令,缺乏直观的全局比例感。dust 将目录大小计算与层级结构可视化融为一体,输出一棵带占用百分比与字符条形图的目录树,让大块空间分布一目了然。
df:确定哪个文件系统或挂载分区容量报警
dust:直观展示目标目录树内各层级子项的空间占用占比需要明确的是:dust 仅负责只读分析与终端展示,不会自动删除任何文件。本文以 dust 1.2.5 为规范与本地实测版本。

1. 排查起点:先确认文件系统范围#
绝不要在磁盘告警时盲目直接执行 dust /。根目录包含虚拟文件系统与外部挂载盘,全盘扫描会导致大量的无意义 I/O。
规范的第一步是使用 df 查看容量与挂载分区:
df -h
df -h /path/to/suspect确认告警的是系统根分区(/)、独立数据盘(如 /data),还是 WSL2 中挂载的 Windows 分区(/mnt/c)。定位到大致目标后,再针对可疑顶层目录启动 dust:
dust /path/to/suspect理解 dust 独特的默认展示方向#
dust 在终端中输出的排版逻辑与常规命令有所不同:
- 默认倒排(自底向上):dust 默认将总计行(100% 根目录)打印在终端输出的最底部,最大的子分支紧随其上,较小的项排在最上方。这样设计的目的是当扫描结果较长滚屏时,用户在终端光标停留的最底行能立刻看到最关键的总结与最大瓶颈。
- 正向树形(
-r, --reverse):如果你习惯像文件管理器那样从上往下阅读(总目录在最顶层,子项在下方展开),只需要加上-r参数。
在测试小型样本时,各分支的显示字节数由底层文件系统的最小分配单元(块大小)决定,读者应重点关注条形图比例与相对排位,而非跨机器比较微小的字节差异。
2. 核心参数:控制扫描深度与聚焦范围#
面对数万个文件的庞大目录树,未经限制的输出很容易刷满终端缓冲区。掌握以下四个旋钮是高效定位的关键:
1. 限制条目数量(-n, --number-of-lines)#
默认情况下,dust 会尝试填满当前终端窗口的高度。如果只想聚焦最突出的几个大项:
dust -n 15 /var注意:
-n仅限制终端最终渲染输出的行数,并不代表 dust 内部只扫描了 15 个文件。为了找出究竟谁最大,工具仍然需要完整遍历目标路径。
2. 控制展示深度(-d, --depth)#
在初次探查大型未知目录时,使用深度限制可以快速识别大分支,避免被深层碎片文件淹没:
dust -d 2 /var一旦在第 2 层锁定了热点(例如发现 /var/log 占据了 80% 的体积),再进一步将热点作为新起点深入分析:
dust -d 3 /var/log3. 限制在同一文件系统(-x, --limit-filesystem)#
这是生产环境与根目录排查中最关键的安全参数:
dust -x -d 2 /-x 会严格阻止 dust 跨越挂载点边界。它能确保扫描不会意外深入到:
- 伪文件系统:
/proc、/sys、/dev(这些不是真实磁盘占用); - 远程挂载:NFS、CIFS/Samba、SSHFS 网络存储;
- 宿主机桥接:WSL2 中的
/mnt/c或容器内挂载的外部卷。
4. 仅看目录或仅看文件#
-D, --only-dir:输出中隐藏普通文件,只看各层级目录的聚合大小;-F, --only-file:跳过目录聚合,直接按单个文件大小排序,迅速揪出误存的单个大 tar 包、iso 镜像或孤立核心转储(core dump)。
3. 场景一:定位项目工程构建产物的膨胀#
在日常编码中,代码仓库经常会在几周内膨胀到数个 GiB。先从仓库根目录做全局纵览:
dust -n 25 -d 2 .如果发现 build/、target/、.next/、node_modules/ 或编译缓存占据绝大多数空间,再单独对热点目录展开:
dust -d 3 target规范清理准则#
在确认空间被编译中间件占据后,切勿无脑直接执行 rm -rf:
- 优先使用构建系统内置的清理目标:
# Rust 项目 cargo clean # CMake 项目 cmake --build build --target clean # Node.js 项目 npm run clean - 警惕误删开发数据:在很多团队中,开发者习惯临时将测试数据库(如 SQLite 文件)、本地密钥或未提交的测试样本随手扔在
build/或缓存子目录下。递归删除前,先核对路径中是否存在不可恢复的资产。
4. 场景二:排查日志与系统目录满溢#
排查 /var/log 或 /var/lib 时,普通用户账号常会遇到读取权限限制:
dust -n 20 -d 2 /var/log如果某些子目录权限为 0700,dust 会因无法进入而导致该分支统计不全。可以附加 --print-errors 查看哪些路径被跳过:
dust --print-errors -d 2 /var/log典型热点与治理方式:#
- Systemd Journal 日志过大:
如果发现
/var/log/journal/占用了几十个 GiB,不要直接执行rm -rf,否则可能导致 journald 状态异常。使用其自带的轮转与修剪机制:# 查看当前 journal 真实占用 journalctl --disk-usage # 仅保留最近 7 天的日志,或限制总体积在 2G 以内 sudo journalctl --vacuum-time=7d sudo journalctl --vacuum-size=2G - Docker / 容器存储层堆积:
如果发现
/var/lib/docker/overlay2异常庞大,严禁手工去该目录删除层文件,这会破坏 Docker 容器镜像的元数据关联。应当使用 Docker 提供的生命周期命令:docker system df docker system prune -a --volumes
5. 存储深度概念:磁盘块分配与文件名义长度#
运行 dust 时,可能会发现它的统计值与某些通过 ls -l 看到的值不一致。这是因为文件存在两种不同的大小口径:
Apparent Size (名义大小/文件长度):文件逻辑上包含的字节数
Disk Usage (物理磁盘占用):操作系统为该文件实际分配的存储块(Blocks)总和- 默认行为:dust 默认统计物理分配的磁盘块(类似于
du),这是判断磁盘空间满溢的真实指标; - 名义大小参数(
-s, --apparent-size):使用逻辑长度进行统计。
为什么两者会有巨大差异?#
- 小文件空间放大:Linux 文件系统(如 ext4)通常以 4096 字节(4 KiB)为一个 Block。一个只包含 10 个字节的文本文件,在磁盘上也必须分配一个完整的 4 KiB 块。如果目录内有 100 万个微小文件,名义大小可能只有 10 MB,但物理占用高达 4 GB。
- 稀疏文件(Sparse Files):某些数据库文件、虚拟机镜像或日志截断文件,名义长度可能有 100 GiB,但实际写入的非空块只有 2 GiB。如果不加说明地按
-s扫描,会误以为该文件吞噬了整块磁盘。 - 压缩文件系统与去重:在支持透明压缩的 ZFS 或 Btrfs 上,物理占用可能远小于名义大小。
验证单个疑难文件时,可使用系统命令对照核查:
stat <file-name>
du -h <file-name>
du -h --apparent-size <file-name>6. 排查隐蔽故障:Inode 耗尽与已删除未释放#
在排障实践中,经常会遇到两次“诡异”的满盘现象:
现象 A:磁盘字节明明很空,却报错“No space left on device”#
这是典型的 Inode(索引节点)耗尽。Linux 文件系统创建每个文件都需要消耗一个 Inode。当微小文件数量超出上限时,磁盘即使还有数百 GiB 空间也无法新建任何文件。
- 使用
df -i检查各分区的 Inode 使用率; - dust 提供了专门的 Inode / 文件计数模式:使用
dust -f -d 2 /path-f, --filecount时,输出的不再是字节数,而是该目录下包含的子文件数量。你可以像排查体积一样,迅速找到哪个目录下堆积了数百万个无效 Session 文件或临时锁文件。
现象 B:df 显示 100% 满,但 dust 怎么扫都找不到大文件#
如果 dust 统计出的所有文件体积加起来只有 20 GiB,但 df 显示 100 GiB 磁盘已满,常见原因包括:
- 进程持有已删除文件的句柄:当一个大日志文件被
rm移除后,如果有运行中的守护进程(如 nginx 或 java)仍然打开着该文件的句柄,文件系统就不会释放其占用的磁盘块。使用以下命令找出被持有者:释放方法是平滑重启(graceful reload)或重启对应的应用程序,让其关闭文件句柄,内核随后会自动回收磁盘空间。sudo lsof +L1 # 或过滤 deleted sudo lsof | grep deleted - 挂载点覆盖(Mount Shadowing):如果在
/mnt/data目录原本就有 50 GiB 文件的情况下,将另一块新磁盘挂载到了/mnt/data上,原有文件会被新挂载点“遮盖”。底层原文件依然占据根分区空间,但所有对该路径的扫描都只能看到新磁盘的内容。
7. WSL2 环境中的磁盘空间治理陷阱#
在 WSL2(Windows Subsystem for Linux)下使用 dust 时,必须了解其背后的虚拟化存储机制:
- WSL2 原生虚拟磁盘(ext4.vhdx):在 WSL2 内部的
/home或/var中删除数十 GiB 文件后,在 Windows 宿主机上会发现ext4.vhdx文件的大小完全没有减少。这是因为虚拟硬盘文件默认只会扩容、不会自动动态收缩。- 若要回收 Windows 宿主磁盘空间,需要在 Windows PowerShell 中执行 WSL 磁盘压缩或配置 sparse 属性:
wsl --manage <Distro> --set-sparse true - 跨系统扫描性能剧烈下降:如果在 WSL2 中执行
dust /mnt/c/Users,数据需要跨越 9P/virtio-fs 虚拟化总线,且受宿主 Windows Defender 实时文件监控影响,扫描速度会比在 Linux 原生文件系统上慢数倍至数十倍,并产生高 CPU 占用。排查 Windows 目录时,优先在 Windows 宿主使用原生工具。
8. 工具选型矩阵:dust、du、ncdu 与 df#
在实际运维与开发工具链中,这四个工具应当各司其职:
| 工具 | 优势与核心定位 | 不适用场景 |
|---|---|---|
df | 毫秒级瞬时查看文件系统容量与 Inode 总览 | 无法知道空间具体在哪个子目录 |
dust | 快速人工交互分析,比例直观,无需记忆复杂管道组合 | 自动化 Shell 脚本解析、缺少交互式删除入口 |
ncdu | 基于 ncurses 的双向交互界面,支持在 TUI 内逐层穿透与确认删除 | 快速打印一张输出直接离开终端的场景 |
du | POSIX 标准工具,全平台默认内置,适合脚本稳定输出与机器解析 | 人工直观阅读体验差,排查深层目录需要拼装多段管道 |
脚本编程建议:严禁在自动化运维脚本中通过
awk或正则去截取dust的彩色终端树。dust 的字符宽度、ANSI 颜色与条形图格式会随版本变化。在脚本中请始终使用标准的du -sh或du -b。
9. 稳妥的磁盘空间排查实战路径#
在处理磁盘空间报警时,建议遵循以下五步闭环:
# 步骤 1:确认告警挂载点与 Inode 状态
df -h
df -i
# 步骤 2:限定同一文件系统,用深度参数粗筛顶层大分支
dust -x -d 2 -n 15 /var
# 步骤 3:针对可疑大项进行聚焦展开
dust -x -d 3 -n 20 /var/log
# 步骤 4:若怀疑单个大文件,直接拉取文件列表
dust -x -F -n 10 /var/log
# 步骤 5:核实文件属性后再做决策
ls -lh /path/to/large_file
stat /path/to/large_file在进入任何删除步骤之前,必须核实五个关键要素:该文件由哪个服务生成?是否有进程正在写入?该文件是否为业务关键日志?是否存在专用的清理命令?删除后能否自动恢复? 只有全部明确后,才能执行安全清理。
参考资料#
本文采用 CC BY-NC-SA 4.0 许可。