上一篇写完 dust 之后预告过,这次实测 eza-community/eza(星数约 2.38 万,GitHub API 读于 2026-11-10)。
eza 是已经停更的 exa 的社区接班版,口号是「现代、有人维护的 ls 替代品」:默认彩色、能显示 Git 状态、自带树形视图、能画图标。很多教程第一步就是 alias ls=eza。它到底比 ls 好在哪、慢多少、哪些参数和 ls 长得一样意思却不同,我在本机跟 GNU ls 正面比了一轮,顺手踩到一个在脚本里很隐蔽的坑。
本机实测 + AI 辅助整理。测量时间:2026-11-10(Asia/Shanghai)。墙钟用 hyperfine(
-N -w 3 -r 30,目录树那组-r 20),文内写 中位数 ;输出不经终端,目录在页缓存里,属于「热缓存」成绩。本机环境默认NO_COLOR=1、TERM=dumb,下文单独说明颜色。
本机环境
text
OS: Debian 13 (trixie) x86_64,8 核
eza: v0.23.5 [+git](GitHub release 二进制)
ls: GNU coreutils 9.7
git: 2.47.3
安装:apt 又没有
text
$ sudo apt-get install -y eza
E: Unable to locate package eza
本机 Debian 13 源里当天搜不到 eza(README 写了 Debian/Ubuntu 可以加 deb.gierens.de 第三方源,我没加)。直接下官方 release:
bash
curl -sL -o eza.tar.gz \
https://github.com/eza-community/eza/releases/download/v0.23.5/eza_x86_64-unknown-linux-gnu.tar.gz
tar xzf eza.tar.gz # 包里只有一个 ./eza
mkdir -p ~/.local/bin && cp eza ~/.local/bin/
eza --version # v0.23.5 [+git]
[+git] 表示编进了 libgit2,--git 相关功能可用。release 里还有 _no_libgit 版本,体积小但没有 Git 列;以及 musl 静态版,适合老系统。macOS 一般 brew install eza,Rust 用户 cargo install eza。
测试素材
| 路径 | 说明 |
|---|---|
repo/ |
自建 Git 仓库:1 次提交后,改了 src/main.rs、chmod +x src/lib.rs、新增未跟踪 src/new.rs、git add 了 docs/b.md;.gitignore 忽略 build/ 和 *.log;另有好坏两个符号链接、带空格目录、中文目录、隐藏文件 |
many/ |
10000 个空文件,测大目录列表 |
/usr/bin |
本机 743 个条目 |
eza-src/ |
git clone --depth 1 的 eza 源码,780 个条目,测 Git 列开销 |
/usr/share/doc |
1600 个条目(第一层 752 个、符号链接 55 个),测树形视图 |
坑 1:脚本里不带参数跑 eza,什么都不输出
这是我这次最意外的一点。我的测试脚本 stdin 不是终端,在 repo/ 里直接跑:
text
$ ls
README.md
app.log
build
...(9 项,正常)
$ eza
(空,exit 0)
$ eza .
app.log
build
'dir with spaces'
...(9 项,正常)
eza -l、eza -T、eza -la 不带路径时也全是空的,退出码都是 0,不报错。把同一条 eza 放进伪终端(script -qc eza /dev/null)又一切正常。再试:
text
$ echo README.md | eza -l
.rw-r--r-- 7 box 10 Nov 08:55 README.md
也就是说:没给路径、stdin 又不是终端时,eza 会把 stdin 当成文件名列表来读 (help 里对应的开关是 --stdin,但本机不加它也会这样)。stdin 是空的,就列了个寂寞。
在交互终端里你永远碰不到它,但在 cron、CI、ssh host 'eza -l' 带重定向、或者 Agent 工具调用这类非交互环境里,裸 eza 会静默返回空。写进脚本时一律显式写路径:eza -l .。 如果你 alias ls=eza,别名一般不进非交互脚本,影响有限;但手写的 eza 命令要注意。
坑 2:-h 不是 human-readable,-b/-B 和你想的反着来
ls -lh 是「人类可读大小」,到了 eza:
text
$ eza -lh .
Permissions Size User Date Modified Name
.rw-r--r-- 4 box 10 Nov 08:55 app.log
...
-h 是 --header,加一行表头。eza 默认就是人类可读大小 ,不用 -h。同一个 4122 字节的 build.rs:
| 命令 | 显示 |
|---|---|
eza -l(默认) |
4.1k(十进制,小写 k = 1000) |
eza -lb |
4.0Ki(二进制前缀) |
eza -lB |
4122(原始字节) |
ls -lh |
4.1K |
50823 字节的 Cargo.lock:eza 默认 51k,ls -lh 是 50K。两边单位制不同,数字对不上不是 bug。要和 du、ls -lh 的结果对账,用 eza -lb;要喂给脚本,用 eza -lB。
坑 3:目录大小默认是 -,ls -l 那行 total 也没了
text
$ ls -l
total 28
...
drwxr-xr-x 2 box box 4096 Nov 10 08:55 build
$ eza -l .
drwxr-xr-x - box 10 Nov 08:55 build
eza 默认不显示目录 inode 的 4096,也不输出 total 行;硬链接数和 group 列默认也不显示(要 -H、-g)。想看目录内容总和要加 --total-size:
text
$ eza -l --total-size .
drwxr-xr-x 9 box 10 Nov 08:55 build
drwxr-xr-x 28 box 10 Nov 08:55 src
这里的 9、28 是目录里文件长度相加(字节),不是磁盘块占用,需要块占用还是用 du 或上一篇的 dust。
卖点 1:Git 状态列,真的好用
text
$ eza -l --git --no-user --no-time .
.rw-r--r-- 4 -I app.log
drwxr-xr-x - -I build
drwxr-xr-x - -N 'dir with spaces'
drwxr-xr-x - N- docs
lrwxrwxrwx - -N link-broken -> nope
lrwxrwxrwx - -- link-ok -> README.md
.rw-r--r-- 7 -- README.md
drwxr-xr-x - -N src
drwxr-xr-x - -N 中文目录
$ eza -l --git src docs
src:
.rwxr-xr-x 4 box 10 Nov 08:55 -M lib.rs
.rw-r--r-- 20 box 10 Nov 08:55 -M main.rs
.rw-r--r-- 4 box 10 Nov 08:55 -N new.rs
docs:
.rw-r--r-- 2 box 10 Nov 08:55 -- a.md
.rw-r--r-- 7 box 10 Nov 08:55 N- b.md
两个字符分别是「暂存区 / 工作区」:N- 是已 git add 的新文件,-N 是未跟踪,-M 是改了没暂存,-I 是被 .gitignore 忽略,-- 是干净。和本机 git status --short 逐项对得上,只改了权限的 lib.rs 也被标成 M。目录那一格会汇总子项状态(src 显示 -N)。
另外两个和 Git 相关的开关:
text
$ eza -l --git-repos fixtures
drwxr-xr-x - box 10 Nov 08:55 | main eza-src
drwxr-xr-x - box 10 Nov 08:55 - - many
drwxr-xr-x - box 10 Nov 08:55 + master repo
--git-repos 把每个子目录是否是仓库、当前分支、是否干净列出来(本机对照:干净的 eza-src 显示 |,有改动的 repo 显示 +,- 表示不是仓库),一个目录里放很多项目的人会喜欢。--git-ignore 则直接把被忽略的东西藏掉,-T --git-ignore 时 build/ 和 app.log 都不见了,比自己写 -I 模式省事。
卖点 2:自带树形和代码统计
text
$ eza -T .
.
├── app.log
├── build
│ └── out.bin
├── 'dir with spaces'
│ └── 'f g.txt'
├── docs
│ ├── a.md
│ └── b.md
├── link-broken -> nope
├── link-ok -> README.md
├── README.md
├── src
│ ├── lib.rs
│ ├── main.rs
│ └── new.rs
└── 中文目录
└── 文件.txt
带空格的名字自动加了单引号(ls 输出到非终端时不加),中文名对齐正常。-L 1 限制深度;-a 才显示 .gitignore、.hidden 这类隐藏文件。
v0.23.5 还有个 --code,按语言统计行数:
text
$ eza --code .
Language Files Lines Code Comments Blanks Code %
Rust 3 4 4 0 0 57.1%
Markdown 3 3 3 0 0 42.9%
Total 6 7 7 0 0 100.0%
其他和 ls 的差异
- 排序 :默认按名字不分大小写(
README.md排在link-ok后面);--sort=Name(大写 N)才是大写优先;--group-directories-first目录置顶。 - 时间格式 :默认
10 Nov 08:55;--time-style=long-iso输出2026-11-10 08:55,iso是11-10 08:55。 - 八进制权限 :
-o多一列0755/0644,chmod 时很方便。 - 筛选 :
-D只列目录,-f只列文件。 - 报错 :
eza nonexist输出"nonexist": No such file or directory (os error 2),退出码 2,和ls一样。 --absolute要带值 :eza --absolute .会把.当成它的值而报错,要写--absolute=on。
颜色和图标
本机环境带 NO_COLOR=1,eza 会尊重它,默认输出纯文本;--color=always 强制上色后权限位、大小、用户名、时间各有颜色,可执行文件名高亮。--icons=always 会在名字前加 Nerd Font 图标,终端字体不是 Nerd Font 时就是一排方块,建议只在本地终端的 alias 里开,别写进要给别人看的脚本输出。
速度:比 ls 慢,但大多数目录感知不到
hyperfine -N,中位数:
| 场景 | GNU ls | eza | 倍数 |
|---|---|---|---|
10000 文件 -1 |
6.1 ms | 39.2 ms | 约 6.4× |
10000 文件 -l |
21.5 ms | 48.0 ms | 约 2.2× |
10000 文件 -la |
23.7 ms | 49.5 ms | 约 2.1× |
/usr/bin(743 项)-1 |
1.3 ms | 3.2 ms | 约 2.5× |
/usr/bin -l |
3.4 ms | 5.7 ms | 约 1.7× |
内存:10000 文件 -l 时 eza 峰值 RSS 26.3 MiB,ls -l 4.8 MiB。eza -l 的 CPU 时间(91.9 ms)比墙钟(48.0 ms)高,说明它用了多线程去读元数据。
Git 列的开销(eza 源码目录,780 个条目):
| 命令 | 中位数 |
|---|---|
eza -l |
2.0 ms |
eza -l --git |
7.9 ms |
eza -T |
6.1 ms |
eza -T --git-ignore |
18.0 ms |
eza -lT --git |
19.2 ms |
树形视图在大目录上要注意:
命令(/usr/share/doc,1600 条目) |
中位数 |
|---|---|
find /usr/share/doc |
4.2 ms |
eza -T -L 1 |
约 5.6 ms(均值) |
eza -T -L 2 |
109.5 ms |
eza -T |
115.1 ms |
eza -T 的 CPU 时间只有 27.6 ms,墙钟却 115 ms,大部分时间不在计算上;我加 --no-git 后均值仍是 104.9 ms,所以不是 Git 造成的,具体卡在哪我没继续深挖。结论是:日常 ls 场景慢几毫秒无感,深目录别随手 eza -T,先加 -L 2。
我会怎么配
bash
# ~/.bashrc / ~/.zshrc,只在交互 shell 生效
alias ll='eza -l --git --group-directories-first --time-style=long-iso'
alias lt='eza -T -L 2 --git-ignore'
# 脚本里:继续用 ls,或者写 eza -l .(显式路径)
小结
| 项 | 本机结果 |
|---|---|
| 版本 / 星数 | eza v0.23.5 ,约 2.38 万 星(2026-11-10) |
| 安装 | apt 无 eza → GitHub release → ~/.local/bin |
| 最大的坑 | 非终端 stdin 时裸 eza 读 stdin,输出为空、exit 0;脚本写 eza -l . |
| 参数差异 | -h 是表头;默认十进制 4.1k;-b 二进制 4.0Ki;-B 原始字节 |
| Git 列 | 与 git status --short 对得上;-l --git 2.0 → 7.9 ms |
| 速度 | 一万文件 -l 48.0 ms vs ls 21.5 ms;/usr/bin -l 5.7 vs 3.4 ms |
| 树 | /usr/share/doc 全树 115 ms,find 4.2 ms |
一句话:eza 不是更快的 ls,而是更好读的 ls。Git 状态列、--git-ignore 和树形视图是真香点;代价是几毫秒到几十毫秒、几倍内存,以及几个和 ls 同名不同义的参数。放进交互 alias 很值,放进脚本要写显式路径。
完整测量日志在本机 eza/measurements.txt、bench-*.json 与 out-features.txt;完整安装脚本包和进阶踩坑表以后会整理上架 Gumroad,先关注专栏「GitHub实测笔记」。
上一篇:dust 本机实测(/usr 扫树中位 92ms / du -sh 80ms)。
下一篇预告:ajeetdsouza/zoxide------更聪明的 cd,看它的跳转排名怎么算、和 shell 集成踩不踩坑。有问题评论区见,看到都会回。