bat:带翅膀的 cat,终端里的代码阅读器
阅读时间: 大约 10 分钟
bat:带翅膀的 cat,终端里的代码阅读器

bat 是德国开发者 David Peter(GitHub ID sharkdp,同时也是 fd 的作者)发起的开源项目,官方自我定位只有一句话:“a cat(1) clone with wings”——一个长了翅膀的 cat。它在 POSIX cat 之上叠加了语法高亮、Git 集成、不可见字符高亮和自动分页。项目版权年份标注为 2018–2025,以 MIT / Apache-2.0 双协议发布,当前维护者包括 sharkdp、eth-p、keith-hall、Enselic 四人。
一、为什么需要它
经典 Unix cat 把文件原样吐到终端:没有行号、没有颜色、不区分语言。在纯文本年代这够用,但当你在 SSH 会话里排查一个上千行的日志或配置时,只读裸文本意味着两件事:一是要自己心算”这是第几行”,二是无法快速定位 if、字符串、注释等结构。同时,cat 在管道里被大量用作”把文件喂给下一个命令”的胶水,所以任何替代品都不能破坏这个语义。bat 的设计目标正是在”好看地读”和”仍然能被当 cat 用”之间取得平衡。
二、它是什么
按官方 README 的说法,bat 要达成四件事:
- 提供漂亮、先进的语法高亮;
- 与 Git 集成,显示文件相对暂存区的修改;
- 成为 POSIX
cat的直接替代品(drop-in replacement); - 提供用户友好的命令行界面。
它不是一个编辑器,也不是一个分页器——需要复杂 diff 审阅时官方推荐配合 delta;需要交互式文件浏览时则是 fzf/ranger 这类工具的领地。
三、技术机制
语法高亮底层调用 Rust 生态的 syntect库。关键设计在于:syntect 直接读取 Sublime Text 的 .sublime-syntax 定义与 .tmTheme 主题文件。这意味着 bat 不自己维护一份语言列表,而是复用 Sublime Text 积累多年的语法包生态;用户也可以把第三方 .sublime-syntax 放进 $(bat --config-dir)/syntaxes 再执行 bat cache --build 自行扩展语言,主题同理(注意官方注明:较新的 .sublime-color-scheme 暂不支持,只认 .tmTheme)。

Git 集成的机制是:bat 在渲染前调用 git 查询当前文件相对 index 的差异,把改动行标记画在左侧边栏(修改用黄色波浪符、新增用绿色加号,见上图)。这要求你确实在一个 Git 工作树里、且文件被 Git 跟踪——否则那一列就是空的行号。

第三个机制是不可见字符可视化。-A/--show-all 把空格渲染为点、Tab 渲染为箭头、行尾补上 LF/CR 标记,这在排查”为什么这行对不齐""为什么粘贴进来的缩进怪怪的”时非常实用。
分页方面,bat 默认在输出超过一屏时把自己交给分页器(默认 less),并自动给 less 追加 -R -F -K 等参数以正确渲染 ANSI 颜色、小屏自动退出。但它有一个被官方反复强调的回退行为:一旦检测到非交互终端(输出被管道或重定向到文件),无论你设了什么 --paging,bat 都退回成纯 cat,只打印原始内容。这就是它敢被 alias cat='bat' 的原因。
四、关键数据与行为口径
下表是从官方 README 可直接核对的事实:
| 项目 | 官方口径 |
|---|---|
| 实现语言 | Rust(从源码构建需 Rust 1.79.0 或更高) |
| 高亮引擎 | syntect,复用 Sublime Text .sublime-syntax / .tmTheme |
| 默认深色/浅色主题 | Monokai Extended / Monokai Extended Light |
| Ubuntu 收录版本 | 自 20.04(Focal)起官方仓库可用 |
| Debian 收录版本 | 自 2021 年 8 月(Debian 11 Bullseye)起 |
| 可原生识别编码 | UTF-8 与 UTF-16,其余需先 iconv 转码 |
| Tab 处理 | bat 自己把 Tab 展开为 4 个空格,分页器侧的 Tab 设置不生效 |
| 协议 | MIT 或 Apache-2.0 双许可 |
五、评测与口径批判
bat 这类工具没有第三方压测数字可引用,它的”性能”叙事主要是 Rust 带来的启动速度与低内存占用,但官方 README 并未给出任何 benchmark 数据,因此本文不引用”比 cat 快 N 倍”之类说法——这属于社区口碑,不是官方可核对结论。真正需要批判性看待的是它的默认行为:
- 自动分页会改变交互节奏:如果你把
cat别名成裸bat,每次看小文件也可能进分页器,官方因此建议写成alias cat='bat --paging=never'来保留 cat 语义。 - Git 标记是”相对 index”而非工作树全量 diff:它显示的是和暂存区的差异,未跟踪文件、未
git add的改动呈现方式和你预期可能不同。 - 管道中的语法高亮会失效或退化:从 stdin 读取时,只有当首行 shebang(如
#!/bin/sh)能推断语言时才高亮,否则要用-l手动指定。
六、适用 / 不适用场景
适合:在终端里读代码、配置、日志时想要行号和颜色;做 fzf --preview "bat --color=always ..." 的文件预览器;把 man、git show、tail -f 的输出上色;作为脚本里 cat 的无缝替换。
不适合:需要在脚本里精确复制带格式的原文——行号和边栏会污染复制结果,应改用 -p/--plain;处理非 UTF-8/UTF-16 的旧编码文件;在不支持 truecolor 的老旧终端里期待所有主题都好看;在 Cygwin 里直接传 /cygdrive/* 路径(官方明确不原生支持)。
七、优势与局限
优势:生态集成极深——fzf、fd、ripgrep(经 batgrep)、git show、man、prettier 都有现成玩法;跨发行版打包齐全;主题与语言可自行扩展而不用改源码。
官方自认的局限(nuance):
- 在较老的 Debian/Ubuntu 上可执行文件名是
batcat(与另一个包命名冲突),需要建软链或别名。 - 官方没有推荐的 snap 包,现存 snap 不受支持且”可能有问题”。
- Windows 上需要先装 Visual C++ Redistributable;系统自带的
more分页器功能很弱,老旧less在 Windows 上还会画错颜色。 - Manpage 语法”仍需完善”,
--help文本高亮语法被官方标注为实验性,欢迎报 issue。 - 8-bit 主题只有
ansi、base16、base16-256三套,且官方明确说”大多数高亮主题并未为 8-bit 颜色优化”,强烈建议 truecolor 终端并正确设置COLORTERM。 - 当输入文件本身含 ANSI 转义码或控制字符时输出会错乱;官方为此提供
--strip-ansi和面向不可信输入的--sanitize(会把 bidi/零宽等不可见格式字符替换为替换符)。
八、它意味着什么
bat 代表了近年 Rust 系”现代 Unix 工具”的典型路线:用一个小而美的二进制替换一个四十岁的标准命令,保留其管道语义,再把现代编辑器里的视觉体验搬回终端。它本身不改变你怎么写代码,而是降低”在终端里读代码”的认知成本。对已经习惯 cat 的人,迁移成本几乎为零;对还在用 cat 看日志的人,它是性价比极高的一步升级。