nushell — 让命令之间传 Excel 表而不是传纸条
是什么
nushell(命令是 nu)是一个用 Rust 写、把命令之间流动的东西从字节流换成结构化表格的 shell。日常类比:bash 里命令之间像在传纸条——每段拿到都得自己重新解析;nushell 里命令之间像在传 Excel 表——每段拿到的就已经是带列名的行列。
具体看一行:
ls | where size > 1mb | sort-by modified | first 5ls 输出不是文字,而是一张 table,列叫 name / size / modified / type。where size > 1mb 直接按列名过滤,不用 awk '{print $5}' 那种数第几列。
这就是 nushell 想推的核心:shell 也能像 SQL 那样按字段操作数据。
为什么重要
不学 nushell 也不影响干活,但理解它能让你看清三件事:
- shell 的 pipeline 不是只能传字节流 —— 1973 年 Unix 决定 pipeline 传字节,是当年内存极小的妥协;50 年后这个默认值开始挡路
- shell 也可以有类型系统 —— int / string / list / record / table 全是一等公民,命令签名能写成
path -> table - PowerShell 不是孤例 —— 微软 2006 年就做了对象 pipeline,nushell 把这个想法做成开源、跨平台、Rust 实现
如果你经常 curl ... | jq ... | awk ... | xargs ... 调 4 个工具拼一行,nushell 的卖点就是这一行变成 4 段同语言、不用记 4 种小语法。
核心要点
nushell 和 bash 最根本的差别是 三处:
-
管道传 value 不传 byte:
ls | first 1给你的是一行 record(有 name/size 等字段),不是一行文本。下一条命令按字段访问,不用 cut/awk。 -
数据格式原生支持:
open config.json直接解析成 record,open data.csv解析成 table,open log.parquet也行。不用先 cat 再 jq 再 awk。 -
静态类型:每个命令都有签名,比如
where: condition -> table。写错列名当场报错,不是跑到一半才崩。
加上一个故意的设计:不兼容 POSIX。老的 .sh 脚本跑不了,nushell 团队认为修补 POSIX 语法(变量分词、引号、错误处理)的坑不如重来——这点和 fish 同源。
实践案例
案例 1:找占用大的文件
bash 里要这样:
ls -la | awk '{ if ($5 > 1048576) print $5, $9 }' | sort -rn | head -5nushell 里:
ls | where size > 1mb | sort-by size --reverse | first 5逐部分解释:
ls返回 table,列name / size / modified / typewhere size > 1mb直接按列名过滤,1mb是字面量——nushell 懂大小单位sort-by size --reverse按列排序,不用记sort -k 5 -rn哪个标志干啥
bash 那行任何一个空格、引号、$5/$9 写错都崩;nushell 这行靠列名定位,写错列名当场报。
案例 2:处理 JSON 不用 jq
open package.json | get dependencies | columns逐部分解释:
open package.json解析 JSON 成 recordget dependencies取出dependencies字段,仍是 recordcolumns列出所有键名
bash 等价:cat package.json | jq '.dependencies | keys[]'——要会 jq 的查询语法。
nushell 把 JSON 当成它自己的数据模型,直接复用同一套命令。
案例 3:进程过滤
ps | where cpu > 50 | select pid name cpu mem逐部分解释:
ps也是 table,列pid / name / cpu / mem / statuswhere cpu > 50按列过滤select只保留这几列输出
bash 等价要 ps aux | awk '$3 > 50 {print $2, $11, $3, $4}',得记 aux 输出第几列是 CPU。
案例 4:跨格式互转
open users.csv | where age > 30 | to json | save adults.json逐部分解释:
open users.csv解析 CSV 成 tablewhere age > 30按列过滤to json把 table 序列化成 JSON 文本save adults.json写文件
bash 要先 csvkit 装一套、再 jq 装一套,nushell 把 CSV/JSON/YAML/TOML/Parquet 全部当成同一套 table 看。
踩过的坑
-
老
.sh跑不了:故意的,不是 bug。nushell 不打算兼容 POSIX,要跑老脚本只能bash old.sh显式调 bash。 -
生态远小于 bash:
oh-my-bash、zsh-autosuggestions这些生态在 nushell 还在补。装 plugin 用register注册,不像 bash 直接 source。 -
0.x 长达 5 年:2019 启动,2025 才发 1.0。学习路上随手搜到的旧博客可能命令名都改了——
ls | where size > 1mb在某些版本叫lt 1mb,要看你用的版本文档。 -
不能完全替代 bash 当系统 shell:很多发行版的启动脚本、Dockerfile RUN 都假设 sh,nushell 适合当交互 shell + 写自己的脚本,不适合替换
/bin/sh。
历史小故事(可跳过)
- 2006 年:微软发 PowerShell,第一个把”对象 pipeline”做进主流 shell。但绑死 .NET、闭源、Windows 限定。
- 2019 年:Jonathan Turner(Rust 编译器组前成员)发起 nushell,目标是”PowerShell 的想法 + Rust 实现 + 跨平台 + 开源”。和 Andres Robalino、Yehuda Katz 一起推。
- 2019-2024 年:5 年 0.x,命令名反复改、生态慢慢起来、plugin 系统成熟。
- 2025 年:发 1.0,承诺 stable API。从想法到 stable 用了 19 年,跨了三波人。
适用 vs 不适用场景
适用:
- 数据探索:日志、CSV、JSON 反复 grep/awk 想成 SQL 风格
- 跨格式转换:
open data.json | to csv | save data.csv一行 - 自己写的运维脚本,不需要给别人传
不适用:
- 给别人发的 install.sh / Dockerfile RUN
- 已经精通 bash + jq + awk,迁移成本不划算
- 极致性能场景(结构化处理有开销,传字节最快)
学到什么
-
pipeline 模型可以重新设计:传字节流是 1973 年的工程妥协,不是物理定律。50 年后内存够大、CPU 够快,传结构化数据完全成立。
-
类型系统能进 shell:以前觉得 shell 必须是动态、字符串、随便组合。nushell 证明加上静态类型,写错当场报、不跑到一半崩,体验反而更稳。
-
故意不兼容旧标准:fish 不兼容 POSIX、nushell 不兼容 POSIX、Deno 不兼容 npm。“放弃兼容”反而成为这一代工具的共同选择——兼容旧设计的代价已经超过了新设计的红利。
延伸阅读
- 官网:nushell.sh(左侧”Book”是入门最快的路径,比 GitHub README 详)
- 视频:Jonathan Turner — Nushell: Modern Shell for the GitHub Era(作者讲为什么要做这个)
- 灵感对比:PowerShell 的对象 pipeline——理解 nushell 等于一半理解 PowerShell