dust 本机实测:/usr 扫树中位 92ms、du -sh 80ms;-s 不是汇总,稀疏文件 0→100Mi

6 阅读9分钟

上一篇写完 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.bin5 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.bintruncate 出的 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 -sh4.0 ms3.1 MiB
du -hd 14.8 ms3.1 MiB
du -ah4.8 ms3.1 MiB
dust -P -n 2020 ms(约 5.1×)4.2 MiB
dust -P -n 20 -d 118 ms4.2 MiB

这一组里 du 经常低于 5 ms,hyperfine 有「壳启动时间校准不够」的警告,所以只把倍数当量级,不当精密赛车成绩。小目录上 dust 更重,和之前 fd 那篇「小目录反而 find 更快」是同一类现象。

/usr(3.7G、约 6.2 万条目)更有参考价值:

命令中位数峰值内存
du -sh /usr80 ms3.1 MiB
du -hd 1 /usr64 ms3.1 MiB
du -ah /usr72 ms3.1 MiB
dust -P -n 30 /usr92 ms(约为 du -sh 的 1.15×,du -hd 1 的 1.4×)20.7 MiB(约 6.7×)
dust -P -n 30 -d 1 /usr90 ms20.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 差多少。有问题评论区见,看到都会回。