上一篇写完 hexyl 之后预告过,这次实测 bootandy/dust(读星数约 1.26 万,2026-11-08)。
磁盘又莫名其妙满了,很多人第一反应是 du -sh * | sort -h。能用,但输出是一列扁平数字:哪个子目录拖垮了父目录、大文件藏在哪一层,要自己在脑子里拼树。dust 宣传自己是「更直观的 du」:默认画出带占比条的目录树,大项自动往下钻,不必先记 -d 和 -h。它到底好不好读、数字和 GNU du 是否对得上、-s 会不会踩成 du -s 的习惯,我在本机跟 coreutils 的 du 正面比了一轮。
本机实测 + AI 辅助整理。测量时间:2026-11-08(Asia/Shanghai)。墙钟用 hyperfine 2.0.0(
-S -w … -r …),文内关键对比写 中位数(JSON schema 2);输出重定向到/dev/null,目录在页缓存里,属于「热缓存」成绩。本机环境默认带有NO_COLOR=1(文内单独说明)。
本机环境
OS: Debian 13 x86_64,8 核
dust: 1.2.7(GitHub release 二进制)
du: GNU coreutils 9.7
安装又踩了和 hexyl / bat 一类工具类似的 apt 坑:
$ sudo apt-get install -y dust
E: Unable to locate package dust
$ sudo apt-get install -y du-dust
E: Unable to locate package du-dust
官方 README 里 Cargo 包名是 du-dust(不是 dust),Debian/Ubuntu 也常被写成 du-dust 或走 deb-get / pacstall。本机 Debian 13 源里当天两个名字都没有。改走官方 release:
curl -sL -o dust.tar.gz \
https://github.com/bootandy/dust/releases/download/v1.2.7/dust-v1.2.7-x86_64-unknown-linux-gnu.tar.gz
tar xzf dust.tar.gz
mkdir -p ~/.local/bin
cp dust-v1.2.7-x86_64-unknown-linux-gnu/dust ~/.local/bin/dust
dust --version # Dust 1.2.7
macOS 一般是 brew install dust。下文统一写 dust。
测试素材
自己搭了一棵已知大小的目录,再拿整个 /usr 做大目录对照:
| 路径 | 说明 |
|---|---|
big/a.bin + big/b.bin | 各 10 MiB 随机数据 |
nested/a/b/c/deep.bin | 5 MiB,测自动下钻 |
many_small/ | 1000 个 1 KiB 文件(块分配会放大) |
types/ | .png / .jpg / .txt / .py |
.secret.bin + .hiddir/inside.bin | 隐藏文件 2 MiB、隐藏目录 3 MiB |
links/ | 3 MiB 原文件 + 硬链接 + 符号链接 + 悬空链接 |
sparse/sparse.bin | truncate 出的 100 MiB 稀疏文件 |
dir with spaces/ | 带空格的目录和文件名,1 MiB |
整棵树:find 共 1028 个条目、1013 个普通文件(硬链接会让同一个 inode 出现两次),唯一 inode 1012 个。GNU du 给出的占用是 41566208 字节(du -sh 显示 40M),按文件长度计是 143259678 字节(du -sh --apparent-size 显示 137M)。/usr 当天是 3.7G(3915665408 字节)、约 6.22 万 条目、51329 个文件。
实测 1:同一棵树,du 是数字,dust 是占比树
du -hd 1 看到的是扁平列表(按大小排过):
4.0K .../hidden_parent
4.0K .../sparse
1.1M .../dir with spaces
1.7M .../types
3.1M .../links
4.0M .../many_small
5.1M .../nested
21M .../big
40M .../tree
dust -P -n 20(-P 关掉进度条,方便重定向;-n 限制行数)直接画出树:
1.0Mi ┌── hello world.bin│██ │ 3%
1.0Mi ┌─┴ dir with spaces │██ │ 3%
100Ki │ ┌── note.txt │█░ │ 0%
512Ki │ ├── bar.jpg │█░ │ 1%
1.0Mi │ ├── foo.png │██ │ 3%
1.7Mi ├─┴ types │██ │ 4%
2.0Mi ├── .secret.bin │███ │ 5%
3.0Mi │ ┌── inside.bin │████ │ 8%
3.0Mi ├─┴ .hiddir │████ │ 8%
3.0Mi │ ┌── hardlink.bin │████ │ 8%
3.0Mi ├─┴ links │████ │ 8%
3.9Mi ├── many_small │█████ │ 10%
5.0Mi │ ┌── deep.bin │██████ │ 13%
5.0Mi │ ┌─┴ c │██████ │ 13%
5.0Mi │ ┌─┴ b │██████ │ 13%
5.0Mi │ ┌─┴ a │██████ │ 13%
5.0Mi ├─┴ nested │██████ │ 13%
10Mi │ ┌── a.bin │███████████░░░░░░░░░░░ │ 25%
10Mi │ ├── b.bin │███████████░░░░░░░░░░░ │ 25%
20Mi ├─┴ big │██████████████████████ │ 50%
39Mi ┌─┴ tree │███████████████████████████████████████████ │ 100%
不用自己拼层级:big 占一半,两个 10 MiB 文件并列;nested 会顺着 a/b/c 钻到 deep.bin;隐藏文件和隐藏目录默认也会出现。只看一层可以加 -d 1,效果接近 du -hd 1,但保留占比条。
只看文件、不看目录骨架,用 -F:最大的就是 b.bin / a.bin / deep.bin。-t 按扩展名归类时,这棵树上 .bin 占 86%(34Mi),.dat(那 1000 个小文件)占 10%(3.9Mi)。
实测 2:默认按磁盘占用,-s 改成按文件长度
这是本机最有用、也最容易踩的一点。
默认模式下,sparse/sparse.bin 几乎看不见——du 报它占用 0,目录是 4.0K;dust 的 -d 1 里 sparse 也是 4.0Ki。因为稀疏文件没有真正占块。
加上 -s(apparent-size,按文件长度,不是 du -s 的「只汇总」):
6.0Mi ├─┴ links
20Mi ├─┴ big
100Mi │ ┌── sparse.bin │████████████████████████████████ │ 72%
100Mi ├─┴ sparse │████████████████████████████████ │ 72%
139Mi ┌─┴ tree
整棵树从默认的 39Mi 变成 139Mi:那 100 MiB 稀疏文件一下子占了 72%。links 也从 3.0Mi 变成 6.0Mi——硬链接在默认模式下只计一次(dust 显示其中一个名字 hardlink.bin),加上 -s 后 hardlink.bin 和 original.bin 各算 3.0Mi。官方 README 写过:默认不把硬链接计两次,想计两次就加 -s。本机和这段说明一致。
many_small 是另一面:1000 × 1 KiB 的内容长度合计约 1 MiB,但每个文件都要占一个 4 KiB 块,所以默认显示 3.9Mi,-s 后变回 1.0Mi。磁盘快满时看默认值更接近「删了能吐出多少块」;看下载文件、稀疏镜像或「ls -l 那么大」时,才需要 -s。
按文件个数而不是体积:dust -f 总数是 1,012(按 inode),dust -f -s 是 1,013(把硬链接那第二个目录项也算上),和 find -type f / find -type f 再按 inode 去重对得上。many_small 独占 99% 的文件数,体积却只占约 10%——找「小文件爆炸」时 -f 比看体积直观。
实测 3:速度——小目录更慢,大目录和 du 同一量级
先说结论:dust 的卖点是好读,不是比 du 更快。 本机热缓存成绩如下。
自建树(约 40M、一千多个文件):
| 命令 | 中位数 | 峰值内存 |
|---|---|---|
du -sh | 4.0 ms | 3.1 MiB |
du -hd 1 | 4.8 ms | 3.1 MiB |
du -ah | 4.8 ms | 3.1 MiB |
dust -P -n 20 | 20 ms(约 5.1×) | 4.2 MiB |
dust -P -n 20 -d 1 | 18 ms | 4.2 MiB |
这一组里 du 经常低于 5 ms,hyperfine 有「壳启动时间校准不够」的警告,所以只把倍数当量级,不当精密赛车成绩。小目录上 dust 更重,和之前 fd 那篇「小目录反而 find 更快」是同一类现象。
/usr(3.7G、约 6.2 万条目)更有参考价值:
| 命令 | 中位数 | 峰值内存 |
|---|---|---|
du -sh /usr | 80 ms | 3.1 MiB |
du -hd 1 /usr | 64 ms | 3.1 MiB |
du -ah /usr | 72 ms | 3.1 MiB |
dust -P -n 30 /usr | 92 ms(约为 du -sh 的 1.15×,du -hd 1 的 1.4×) | 20.7 MiB(约 6.7×) |
dust -P -n 30 -d 1 /usr | 90 ms | 20.7 MiB |
深度 1 时两边数字对得上,只是单位和取整不一样:dust 报 /usr 一共 3.6Gi(lib 1.4Gi、local 1.2Gi、share 787Mi),du -hd 1 报 3.7G(lib 1.5G、local 1.3G、share 788M)。原始字节是 3915665408,约 3.65 GiB——dust 用 Ki/Mi/Gi 且更像截断到一位小数,GNU du -h 用 K/M/G(同样按 1024)并四舍五入。看到 0.1 的差别先别急着重跑。
网上如果有「dust 比 du 快几十倍」的截图,在这台 Debian 13、热缓存、本机 /usr 上我复现不出来。要的是树和占比,不必指望它取代 du 做计时竞赛。
踩坑清单
坑 1:dust -s 不是 du -s
du -s 是 summarize:只打一行总和。dust -s 是 --apparent-size:按文件长度计,仍然输出整棵树。本机 du -s -h 给出 40M;dust -s 给出带 100Mi 稀疏文件的 139Mi 树。从 du 改口令时,这个习惯最容易带歪。
想少打字、只要总数,dust 这边是看最后一行(或加 --skip-total 把它关掉),没有和 du -s 对等的短选项。
坑 2:数字单位对不上,不代表谁算错了
同一棵树:占用 41566208 字节,dust 显示 39Mi(约 39.65 MiB 截成 39),du -sh 显示 40M。按长度计时,du --apparent-size 是 137M(约 136.6 MiB,且硬链接只计一次),dust -s 是 139Mi(硬链接计了两次,大约多 3 MiB)。对照时先统一「按块还是按长度」,再看显示进位。
坑 3:默认会列出隐藏文件,要忽略得加 -i
和 ls / fd 的「默认不看点文件」相反。本机不加 -i 时能看到 .secret.bin(2.0Mi)和 .hiddir(3.0Mi),总计 39Mi;加上 -i 后这两项消失,总计变成 34Mi。在家目录跑 dust,不想被 .cache 刷屏,记得 -i。
坑 4:没权限时默认只说一句,退出码仍是 0
对一个子目录 chmod 000 之后:
Did not have permissions for all directories (add --print-errors to see errors)
secret 仍出现在树里,大小是 4.0Ki(等于空目录),进程退出码是 0。脚本里如果只看退出码,会以为扫全了。加上 --print-errors 才会列出具体路径。官方也说默认最多打一条权限提示,避免 stderr 刷屏。
坑 5:管道里默认不上色;-C 能盖过 NO_COLOR
本机默认有 NO_COLOR=1。输出接到管道时,默认 没有 ANSI 转义;加上 -C / --force-colors 之后,即使 NO_COLOR=1 也能看到颜色(本机测到转义序列)。这点和上一篇 hexyl 不同:hexyl 在有 NO_COLOR 时 --color=always 无效,得 --color=force。把 dust 塞进 watch 或不想要颜色时,用 -c。
坑 6:二进制装到 ~/.local/bin 但 PATH 没带上
$ PATH=/usr/bin:/bin dust --version
dust: command not found
和 fd / bat / hexyl 同一类:release 装法要自己保证 ~/.local/bin 在 PATH 里,或写绝对路径。
另:dust -L 会跟着符号链接走。本机对带悬空链接的目录加 -L 时,直接报 No such file or directory: .../dangling.bin。默认不跟随,悬空链接显示为 0B。
顺手好用的几个参数
dust # 当前目录,行数约等于终端高度
dust -n 30 /var # 只展示约 30 个大项
dust -d 1 # 只看一层,接近 du -hd 1
dust -s # 按文件长度(稀疏文件、硬链接会变大)
dust -i # 忽略隐藏文件
dust -F # 只看文件
dust -D # 只看目录
dust -t # 按扩展名汇总
dust -z 10M # 小于 10M 的不展示
dust -e '\.png$' # 只保留匹配的路径
dust -f # 按文件个数,而不是体积
dust -j # JSON,可交给 jq
dust -b # 不要百分比条
dust -C # 强制颜色
dust -P # 不要扫描进度条
本机 dust -e '\.png$' 准确地只留下 types/foo.png(1.0Mi);dust -z 2M 会把 1 MiB 以下的类型文件和带空格目录滤掉,树更干净。
小结
| 项 | 本机结果 |
|---|---|
| 版本 / 星数 | dust 1.2.7,约 1.26 万 星(2026-11-08) |
| 安装 | apt 无 dust / du-dust → GitHub release → ~/.local/bin |
| 默认单位 | 磁盘占用(块);-s 改为文件长度 |
| 自建树 | 占用 39Mi(du 显示 40M);-s 后 139Mi(稀疏文件 100Mi + 硬链接重复计算) |
/usr 扫树 | dust 92 ms / 20.7 MiB;du -sh 80 ms / 3.1 MiB |
| 小目录 | dust 约 5.1× 慢于 du -sh(20 ms vs 4.0 ms) |
| 坑 | -s≠du -s;显示进位;默认看隐藏文件;权限提示 + exit 0;颜色与 NO_COLOR;PATH |
一句话:dust 没有让「扫目录」本身快过本机的 GNU du,但它把 du -sh * | sort -h 换成一眼能看的占比树,还会自动钻到大文件;用之前先分清默认按块还是 -s 按长度,也别把 -s 当成 du 的汇总开关。
完整测量日志在本机 dust/measurements.txt、bench-fixture.json、bench-usr.json 与若干 out-*.txt;整理版以后会放到 Gumroad,先关注专栏「GitHub实测笔记」。
上一篇:hexyl 本机实测(8MiB 转储中位 102ms / od 696ms)。
下一篇预告:eza-community/eza——更现代的 ls,看默认展示、git 标记和本机相对 ls -l 差多少。有问题评论区见,看到都会回。