duf — df 的彩色表格替代,按设备分组自动忽略伪文件系统
待复核duf 是 muesli 用 Go 写的 df 替代品——在终端敲一下就出一张彩色表格,把磁盘按”本地盘 / 网络盘 / 特殊盘”自动分块,每块都对齐列、用颜色高亮使用率,并默认把 tmpfs / devfs 之类没人想看的伪文件系统藏起来。
日常类比:
- df 是一份手写报表——每列都对不齐,把家用硬盘和 docker 临时挂载点全堆在一起,你得用尺子比着读
- duf 是同一份报表换成 Excel——分了 sheet(local / network / special),每行染了颜色,使用率超 90% 的那行直接标红
跑起来一行:
duf终端就出三张表:本地盘一张、网络盘一张、特殊盘一张,每张表都自带边框和颜色,使用率列会按 0-50% / 50-90% / 90-100% 染绿黄红。
- 不理解它,无法解释为什么
df -h输出里总混着一堆tmpfs/devtmpfs/overlay——这是 Linux 内核暴露给/proc/mounts的伪挂载,POSIX 时代根本没考虑过过滤 - 不理解它,分不清 duf 和
ncdu/dust三者:duf 看挂载点占用、ncdu / dust 看目录递归占用,问题域完全不同 - 不理解它,看不出 procs / btop / glances / bandwhich / duf 这一波系统工具的共同套路:单二进制 + 跨平台 + 表格 / 仪表盘 + 默认彩色 + 不依赖 root 之外的服务
- 不理解它,调试 “为什么 df 显示 100% 但还能写”(Linux ext4 默认给 root 留约 5% reserved blocks)时容易误判——duf 和 df 一样按表面 used/avail 显示,不会单独拆出 reserved
duf 一句话:调系统 syscall 拿挂载列表 + 按 fs 类型分组 + 用 go-pretty 渲染彩色表格。三步拆开:
- 拿挂载列表:每个平台走不同 syscall——Linux 读
/proc/mounts、macOS 调getmntinfo()、Windows 调GetLogicalDrives()+GetVolumeInformation(),BSD 也有自己的接口。这部分被golang.org/x/sys封装抹平。 - 按 fs 类型分组:拿到的每条挂载有
Fstype字段(ext4/apfs/nfs/tmpfs…)。duf 内部维护一张白名单:local(ext4 / xfs / apfs / ntfs / btrfs …)/network(nfs / smb / cifs …)/fuse/special(tmpfs / devfs / overlay …)。默认只显示前两类,--all才全显。 - 渲染彩色表格:用
go-pretty这个库画表格——它已经处理了”列宽自适应 / 边框 Unicode 字符 / 颜色码”,duf 只需要喂行数据。颜色靠termenv检测终端是 truecolor / 256 色 / 单色。
整个二进制约 5 MB,无运行时依赖,brew / apt / pacman 一键装。
案例 1:日常看本地盘
Section titled “案例 1:日常看本地盘”duf输出(简化):
╭─────────────────────────────────────────────────────────────╮│ 2 local devices │├──────────┬──────┬──────┬──────┬───────────────────┬─────────┤│ MOUNTED │ SIZE │ USED │ AVAIL│ USE% │ TYPE │├──────────┼──────┼──────┼──────┼───────────────────┼─────────┤│ / │ 460G │ 312G │ 148G │ [#######....] 67% │ apfs ││ /System │ 460G │ 11G │ 449G │ [#..........] 2% │ apfs │╰──────────┴──────┴──────┴──────┴───────────────────┴─────────╯注意 USE% 列那条进度条是 ASCII 画的,颜色随百分比变化——67% 黄、92% 红、12% 绿。
案例 2:脚本里要 JSON
Section titled “案例 2:脚本里要 JSON”duf --json | jq '.[] | select(.type=="local") | {mp:.mount_point, used:.used, total:.total}'--json 输出每个挂载的全部字段,适合 pipe 给监控脚本。字段是 snake_case:mount_point / fs_type / device_type / total / used / free(见源码 json tag),写成驼峰会拿到 null。
案例 3:只看网络盘
Section titled “案例 3:只看网络盘”duf --only network排查 NFS / SMB 是否挂掉时省得自己写 mount | grep nfs。
案例 4:隐藏吵闹的挂载点
Section titled “案例 4:隐藏吵闹的挂载点”duf --only local --hide-mp '/System/Volumes/Data,/var/lib/docker/*'逐步解释:--only local 先丢掉 network/special;--hide-mp 再按路径通配藏 firmlink / 容器残留。容器或 macOS 上默认输出太吵时,先用这两层过滤,再谈颜色主题。
- macOS firmlinks 显示成多条:从 macOS Catalina 起
/和/System/Volumes/Data是同一份 APFS 数据但挂两次,duf 默认会列两行,需要--hide-fs apfs --only local之类的组合或干脆--hide-mp /System/Volumes/Data - Linux 容器里挂载点污染:
docker exec进去跑 duf 会看到宿主机一堆 overlay 临时挂载,加--only local也没用——根因是容器内/proc/mounts把外面也暴露了,需要--hide-mp /var/lib/docker/* - Windows 网络盘断线卡住:
GetVolumeInformation()调用对断开的Z:\会等几秒超时,duf 没有并发去查每个盘——表现是程序”卡住”几秒。社区有 issue 但没修 - JSON 字段是 snake_case:
--json输出mount_point/fs_type,不是mountPoint;照着别的工具习惯写驼峰会拿到 null - 看到 100% 但还能写:Linux ext4 默认给 root 留约 5% reserved blocks;df / duf 都只显示表面 used/avail,没有单独的 reserved 列——别指望 duf 替你拆账,要用
tune2fs -l看 Reserved block count
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 日常看 “现在哪个盘快满了”——彩色 + 自动分组省心
- 写运维脚本要 JSON 拿磁盘元数据(
--json) - 跨平台脚本(macOS / Linux / Windows 都装一个 duf 而不是处理 df 三种参数语法)
- 排查容器 / 多挂载点环境哪个 mount 异常
不适用:
- 看某个目录用了多少(用
dust/ncdu) - 实时监控磁盘 IO 速率(用 btop /
iotop) - 分析”哪个文件最大”——duf 不递归
- 极简服务器没装彩色终端 / 没字体——
duf --style unicode也可能糊;这种环境直接df -h更稳
历史小故事(可跳过)
Section titled “历史小故事(可跳过)”- 2020-09:muesli(Christian Muehlhaeuser,charm.sh 项目核心作者之一)受不了
df -h输出全是黑白挤一堆,业余开了 duf 仓库,第一版只有 ~600 行 Go - 2021:加入
--json/--hide/--only/--output等过滤,被 Hacker News 推上热门 - 2022:stars 破万,进入 r/commandline 年度推荐
- 2023:Homebrew core / Debian sid / Arch community 主仓收录,成为 macOS / Linux 默认可装
- 2024 起:维护节奏放缓,进入 stable 状态——磁盘列表这事变化少,不需要持续迭代
- POSIX 时代的工具默认输出风格已经过时——df / ps / top 都是 1970-80 年代为电传打字机设计的,2020 年代把它们换成彩色对齐表格几乎是必然
- Go 写跨平台 CLI 的天花板很高:单二进制 + 自带跨平台 syscall 封装(
golang.org/x/sys),加上 termenv / go-pretty 这些库,十几 KB 代码就能做出 brew / apt 都收的工具 - “分组 + 默认隐藏”是好 UX 的本质——df 把所有挂载塞一起是因为 1979 年没人想到会有 docker / tmpfs;duf 默认隐藏伪挂载等于在做信息过滤
- 过滤参数比看似花哨的功能更重要:
--only/--hide/--hide-fs/--hide-mp四个维度的组合让 duf 在容器 / NFS / firmlink 等真实场景能用
- 仓库 README:muesli/duf — 截图很多,10 分钟看完
- charm.sh 系列:termenv / lipgloss —— Go 终端样式生态全家桶
- 表格库:go-pretty —— duf 表格的渲染引擎
- 对比阅读:
man df—— 看 50 年前的输出风格,体会 duf 改了什么