上一篇写完 fd 之后预告过,这次实测 sharkdp/bat(读星数约 6.1 万,2026-11-05)。
日常看源码,很多人还在 cat foo.py 或直接丢进编辑器。cat 快、无脑,但没有行号、没有语法高亮、看不见制表符和行尾空格;less 能翻页,高亮要自己配。bat 宣传自己是「带语法高亮和 Git 集成的 cat」。听起来美好,可高亮不是免费的------大文件上到底慢多少、管道场景会不会把装饰全关掉、Debian 上命令到底叫 bat 还是 batcat,我在本机跟 GNU cat 正面比了一轮。
本机实测 + AI 辅助整理。测量时间:2026-11-05(Asia/Shanghai)。每组先预热 1 次,再取中位数(中等文件 7 次、大文件 5 次),输出丢到
/dev/null,文件都在页缓存里,属于「热缓存」成绩。需要语法高亮时显式加--color=always(因为管道//dev/null不是 TTY,bat 默认会关颜色,否则测到的只是「关掉高亮的 bat」)。
本机环境
text
OS: Debian 13 x86_64,8 核
bat: 0.26.1(GitHub release 二进制,979ba22)
cat: GNU coreutils 9.7
less: 未安装(后面分页相关坑会用到)
安装又踩了和 fd 那篇一样的 apt 坑。本机当天:
text
$ sudo apt-get install -y bat
E: Unable to locate package bat
官方 README 写得很清楚:Debian/Ubuntu 用 apt 装时,可执行文件经常叫 batcat (跟另一个叫 bat 的包撞名),需要自己 ln -s /usr/bin/batcat ~/.local/bin/bat 或 alias bat=batcat。本机 apt 源直接找不到包,batcat 命令也不存在,于是改走官方 release:
bash
curl -sL -o bat.tar.gz \
https://github.com/sharkdp/bat/releases/download/v0.26.1/bat-v0.26.1-x86_64-unknown-linux-gnu.tar.gz
tar xzf bat.tar.gz
mkdir -p ~/.local/bin
cp bat-v0.26.1-x86_64-unknown-linux-gnu/bat ~/.local/bin/bat
# 若你装的是 apt 包,通常是:
# sudo apt install bat
# ln -s /usr/bin/batcat ~/.local/bin/bat
macOS 一般是 brew install bat。下文统一写 bat。
测试素材
复用 ripgrep / fd 那套 corpus,并额外拼了两个大文件:
| 文件 | 大小 | 行数 | 用途 |
|---|---|---|---|
typing.py(Python 标准库) |
130 KB | 3819 | 中等源码,看启动与高亮 |
large_concat.py(多个 .py 拼接) |
2.96 MB | 84019 | 大文本吞吐 |
large_js.js(playwright 两个 bundle 拼接) |
6.67 MB | 164119 | 更大、语法更「重」的 JS |
实测 1:中等源码------高亮一开,从 0.6ms 到 123ms
文件:typing.py(130KB)。TERM=xterm-256color。
| 命令 | 中位数 | 相对 cat |
|---|---|---|
cat |
0.60 ms | 1× |
bat --paging=never --color=never |
4.05 ms | ≈6.8× |
bat --paging=never --color=always |
123 ms | ≈205× |
bat --paging=never --color=always --style=plain |
121 ms | ≈201× |
bat --paging=never --color=always -n |
129 ms | ≈215× |
bat --paging=never --color=always --style=full |
122 ms | ≈203× |
结论先说清楚 :日常「打开看一眼」的体感,bat 的高亮开销在百毫秒量级,人眼几乎无感;但别拿它跟 cat 比吞吐------cat 这条路径几乎只做读和写,bat 还要做语法解析和 ANSI 着色。关颜色后大约慢 7 倍,已经能接受;真正贵的是 --color=always。
输出体积也能侧面说明高亮在干什么(同一文件 132718 字节):
| 模式 | 输出字节 | 含 ANSI |
|---|---|---|
cat / bat --color=never |
132718 | 否 |
bat --color=always --style=plain |
620018 | 是 |
bat --color=always -n |
726950 | 是 |
bat --color=always(默认装饰) |
831010 | 是 |
bat --color=always -A |
1573300 | 是 |
高亮后体积大约变成原来的 4.7~6.3 倍 ;再加 --show-all 接近 12 倍。终端要画的东西变多了,耗时跟着上去并不意外。
实测 2:2.96MB 拼接源码------关颜色 16ms,开高亮 2.4s
| 命令 | 中位数 | 相对 cat |
|---|---|---|
cat |
0.94 ms | 1× |
bat --paging=never --color=never |
16.3 ms | ≈17× |
bat --paging=never --color=always |
2400 ms | ≈2540× |
bat --paging=never --color=always --style=plain |
2359 ms | ≈2496× |
bat --paging=never --color=always -n |
2395 ms | ≈2534× |
关颜色时 bat 大约慢一个数量级出头;一开高亮直接到 2.4 秒 。-n(行号)在关颜色时有明显额外成本(上一组无 --color=always 的测量里,同文件 bat -n 中位数约 48ms,对关颜色的 16ms),但高亮本身已经贵到把行号开销淹没了。
实测 3:6.67MB JS------开高亮 12.4s,这才是标题里的数字
| 命令 | 中位数 | 相对 cat |
|---|---|---|
cat |
1.21 ms | 1× |
bat --paging=never --color=never |
28.4 ms | ≈24× |
bat --paging=never --color=always |
12.42 s | ≈10278× |
同一台机器、同一份热缓存文件:cat 1.2 毫秒,bat 开语法高亮要 十二秒 。这不是黑 bat------它本来就不是为「把几兆 JS 刷到 /dev/null」设计的------而是提醒:别把 bat 当高速 cat 用在脚本流水线里 ;脚本里需要纯文本透传,用 cat,或至少 bat -pp --color=never。
可复现命令(本机路径请自行替换):
bash
# 预热
cat large_js.js >/dev/null
# 关颜色(接近「当 cat 用」)
for i in 1 2 3 4 5; do
TIMEFORMAT='%R'; time bat --paging=never --color=never large_js.js >/dev/null
done
# 开高亮(会明显变慢)
for i in 1 2 3 4 5; do
TIMEFORMAT='%R'; time bat --paging=never --color=always large_js.js >/dev/null
done
实测 4:分页、管道、-n / --style=plain / -A
默认管道会「卸妆」
把 stdout 接到管道时,bat 自动关掉颜色,输出字节数与原文件完全一致:
text
$ bat typing.py | wc -c
132718 # 和文件本身一样,无 ANSI
$ bat --color=always typing.py | wc -c
831010 # 强制保留高亮
这是特性,不是 bug:避免把 \x1b[38;5;... 灌进 grep/wc/重定向文件。代价是------你在脚本里 bat foo \| something 时,看不到高亮;需要颜色时加 --color=always 或 -f(--force-colorization)。
分页:本机没有 less
bat 默认分页器是 less。本机 which less 直接失败(包都没装)。非 TTY / 管道场景下,bat 多数时候会直接把内容打出来,不硬报错;指定 --pager=less 时也可能静默退化。交互终端里若缺少 less,体验会怪------官方也支持 --pager=builtin(内置 minus)或自己指定 more。
日常建议:
bash
# 只想当「更好看的 cat」,永不进分页
alias bat='bat --paging=never'
# 或单次
bat -pp README.md # -pp = --style=plain --paging=never
-n / --style=plain / -A 的有意义差异
在小样例上(hello\tworld + 行尾空格 + NUL):
text
$ printf 'hello\tworld\nline2 \n\0binary?\n' > tabs_sample.txt
$ bat --paging=never tabs_sample.txt
# 制表符、行尾空格、NUL 都「原样」------肉眼几乎看不出问题
$ bat --paging=never -A tabs_sample.txt
hello├─┤world␊
line2··␊
␀binary?␊
-A / --show-all 把 Tab、换行、NUL 变成可见符号,查「明明没字符怎么对不齐」时非常有用。--style=plain(-p)去掉网格/表头等装饰,只留内容(和高亮,若颜色开着);-n 加行号,输出会多出一截前缀(本机 typing.py 关颜色时从 132718 → 151813 字节)。
踩坑清单(都在本机碰到过)
坑 1:Debian/Ubuntu 可能是 batcat,本机 apt 还直接找不到包
text
$ sudo apt-get install -y bat
E: Unable to locate package bat
$ batcat --version
bash: line 1: batcat: command not found
官方说明:apt 装上之后命令经常是 batcat ,因为和另一个 bat 撞名。本机连包都定位不到,最终用的是 GitHub release 二进制。换机器时先 which bat batcat,再决定要不要 ln -s。
坑 2:管道自动关颜色------测速时容易「测错对象」
第一次我把 stdout 接到 /dev/null 就开跑,bat 中位数只有约 2ms(中等文件),心里还想「也就慢一点」。加上 --color=always 之后直接跳到 123ms 。原因写在 --help 里:automatic 模式只在交互终端启颜色。对比高亮成本,必须显式 --color=always,否则你测到的是「卸妆版 bat」。
坑 3:默认分页器是 less,系统没装时行为很「软」
text
$ which less
# 无输出,退出码 1
$ bat --paging=always --pager=less short.py | wc -c
# 不报错,仍可能打出内容(本机管道场景下拿到了文件原文长度)
不要假设「没 less 就会失败」。CI 镜像、精简容器里很常见。需要稳定分页用 --pager=builtin,不需要分页就 --paging=never。
坑 4:未知主题只警告,不失败
text
$ bat --theme=NoSuchThemeXYZ --color=always short.py >/tmp/out 2>/tmp/err
$ echo $?
0
$ cat /tmp/err
[bat warning]: Unknown theme 'NoSuchThemeXYZ', using default.
主题名写错不会非零退出,脚本里检测失败要抓 stderr 或先 --list-themes。本机主题列表一共 28 个。
坑 5:大 JS/大源码开高亮会到秒级
6.67MB 的 JS bundle,--color=always 中位数 12.42s 。不是机器卡死,是语法高亮在干活。预览巨文件、做吞吐脚本,请关颜色或改回 cat。
顺手好用的几个参数
bash
bat -n file.py # 行号
bat -A file.py # 显示 Tab/换行/NUL
bat -pp file.py # plain + 不分页(很像彩色 cat)
bat --color=always -f # 管道里也强制颜色和装饰
bat --list-themes # 看主题
bat --theme=TwoDark file.rs # 换主题
bat -l python dump.txt # 强制按某语言高亮
小结
| 项 | 本机结果 |
|---|---|
130KB typing.py |
cat 0.60ms;bat 关颜色 4.05ms;开高亮 123ms |
| 2.96MB 拼接 py | cat 0.94ms;关颜色 16ms;开高亮 2.4s |
| 6.67MB JS | cat 1.2ms;关颜色 28ms;开高亮 12.4s |
| 管道默认 | 自动关 ANSI,输出字节 = 原文件 |
-A |
Tab/换行/NUL 变可见符号,查隐形字符有用 |
| 坑 | batcat 包名、测速忘开 --color=always、less 缺失、未知主题只警告、大文件高亮秒级 |
一句话:bat 的价值在「人看源码」------行号、高亮、露出身形的空白符;它的成本也在高亮。 当 cat 的替身跑脚本、刷几兆产物到管道里,请关颜色或直接用 cat。它和 ripgrep、fd 是同一作者路线的「友好默认」:交互体验加分,默认真相要自己测。
完整测量日志在本机 bat/measurements.txt;整理版以后会放到 Gumroad,先关注专栏「GitHub实测笔记」。
上一篇:fd 本机实测(/usr 找 *.so,find 72ms / fd 46ms)。
下一篇预告:sharkdp/hyperfine------前面几篇都在手写「预热 + 中位数」,下一篇换成作者同门的基准测试工具,看它怎么处理预热、导出和异常值,并回头复测 bat 这组数字。有问题评论区见,看到都会回。