rubash
可嵌入的 GNU Bash 5.3 兼容引擎:lexer、parser、展开、执行、内建全部进程内, 以字节级兼容 GNU Bash 5.3.0 为目标、原生跑在 Windows 上。 Rubash 本身不是 shell 产品——它是引擎;交互式产品(niubash)建在它之上。
为什么是 rubash
想给编辑器、测试框架、agent 宿主一个「能跑真 bash 脚本的库」,过去只有两条路: 链一个带 POSIX 模拟层的移植 bash(MIT 项目吞不下 GPL 与 msys-2.0.dll), 或者用玩具级的 shell 子集。rubash 是第三条路:MIT 许可、零模拟层、语义对齐被 83 套 GNU 上游语料逐字节测出来的引擎——它作为依赖装进你的项目,而不是作为模拟层装进用户的系统。
Rubash 本身不是 shell 产品
它是从零用 Rust 写的 GNU Bash 语义引擎——词法、解析、展开、执行、内建,全部进程内、headless。它自带一个供兼容性 harness 与工具链使用的参考 CLI;交互式 shell 建在引擎之上:niubash 内嵌 rubash 承担全部 bash 语义,自己拥有行编辑、提示符渲染与补全。
为什么不是移植 bash
「Windows 上的 bash」(Git Bash、MSYS2)装的是骑在 POSIX 模拟层 msys-2.0.dll 上的移植 bash,fork 模拟与路径翻译的怪癖渗进每个脚本。rubash 没有这一层:一个自包含二进制直接说 Win32;语义对齐靠黑盒差分实测,不靠搬运 GNU 代码——GPL 代码零拷贝是成文红线。
兼容是台账,不是口号
对 GNU Bash 自己的 83 套上游语料做 true-baseline 双向测量:83/83 通过、82 套逐字节一致,唯一残差(nameref 1 行)被逐字节证明是 GNU Bash 自身的 coproc 回收竞态。modernish 166/166、bash-completion 452/452、oh-my-bash 252/252 函数环境一致——全部钉成 CI 回归夹具。
语义模型平台中立
进程内子壳、fd 表语义、进程边界三层模型刻意与平台无关:同一份台账从 Windows 带到 Linux / macOS。Linux 上原生构建并运行(WSL 内实测 19/24 套逐字节一致且在收敛),macOS CI 编译绿;Android 双目标进 CI 交叉检查。
核心特性
62 个真内建,全覆盖 GNU Bash 5.3
GNU Bash 5.3 的 61 个内建全部覆盖、无缺失,唯一扩展是 env;另有 Windows 专属 sudo 作为隐藏 host 内建不计入。三层分发(真内建 / 隐藏 fast-path / 外部命令)由仓内文档同步测试守护——改白名单不更新文档,cargo test 直接失败。
零 fork 的三层执行
( list )与 $( ) 从不产生进程:ShellState::clone 复制变量/别名/函数/trap/历史;真句柄 fd 表以 DuplicateHandle 共享同一内核文件对象(POSIX dup 共享 open file description 的等价物);真进程只在真进程边界——外部命令与管道成员走 CreateProcess + os_pipe,作业控制基于 Job Objects。
12 个内联文件命令 + 管道内联臂
pwd、printf、mkdir、touch、chmod、cp、rm、rmdir、cat、sed、mkfifo、tty 在引擎内联执行,echo | cat 这类管道一整个零 fork——subshell 与命令替换零进程创建成本,而脚本可观察的一切与 GNU Bash 行为一致。
可选择的平台身份
Windows 默认 MSYS2 兼容 persona(uname -s → MSYS_NT-…,OSTYPE=msys——为了让生态脚本走它们测得最好的分支),RUBASH_IDENTITY=native 切到诚实原生身份(Windows_NT / OSTYPE=windows)。persona 在 --help、--identity 与 README 处处披露,永不静默。
为 agent 与调试准备的工程面
脚本级函数级 profiler(确定性插桩,非采样)已合并;DAP-first 调试器设计定稿(--debugger,11 个停点 seam 全部锚定既有 DEBUG-trap 分发点,gdb 式 CLI REPL 双前端);引擎跑得动 bashdb 核心调试循环。
跨平台 CI 硬门
ubuntu / macOS / Windows x64 三个真 runner 跑测试,linux-gnu、aarch64-apple-darwin、aarch64-linux-android、armv7-linux-androideabi 四目标交叉检查进同一 CI;单测 698 通过 / 0 失败。跨平台缺口有公开台账(docs/cross-platform-gap-ledger.md),不假装没有。
安装与快速上手
作为依赖嵌入(引擎即库;组织在 crates.io 的三个 crate——rubash、niubash、niubash-runtime——当前均为 1.4.0):
cargo add rubash 从源码构建参考 CLI:
git clone https://github.com/unixwin/rubash.git && cd rubash && cargo build 跑一个脚本(参考 CLI 的用法,即兼容性 harness 的入口形态):
target/debug/rubash path/to/script.sh
首次上手建议直接跑兼容性套件:MSYS_NO_PATHCONV=1 wsl bash scripts/true-baseline.sh
——引擎的口头禅是「测出来的」,基准脚本就是产品的一部分。
深入:嵌入、执行模型与兼容台账
嵌入方式与 1.5.0 蓝图
今天,cargo add rubash 拿到的 1.4.0 已经把引擎当依赖用——niubash 就是第一个完整消费者,
driver 级 API(run_stdin_script 等)已在生产。1.5.0 的蓝图(RFC 已合并,PR rubash#814)把这件事正式化:
四层 workspace 拆分(rubash-core 嵌入面 / rubash-driver 非交互驱动 /
rubash-interactive ConPTY 与主题 / rubash facade 重组出口),
Session 级稳定嵌入 API(输入注入、输出流、生命周期、事件回调、rc 策略钩子),
以及 846 处 env-IPC 形态的引擎/宿主边界逐族替换为 typed bridges。
验收标准一句话:外部编辑器(oh-my-pi、Zed)能嵌入引擎而不需要知道 Windows 的存在——
一个约 500 行的「编辑器内 REPL」演示件构建 rubash-core + rubash-driver 时不引入 ConPTY 或 Win32。
三层执行模型
POSIX fork() 在 Win32 没有等价物。MSYS2/Cygwin 在 syscall 层伪造它——昂贵、脆弱、以怪癖闻名;
rubash 复刻 fork 的语义而非机制:进程内子壳复制变量与 fd 表(fork 的内存面)、真句柄 fd 表实现 POSIX dup
语义(共享同一内核文件对象与文件偏移)、真进程只在真进程边界出现。
结果是 subshell 与命令替换零进程创建成本,而退出码、fd 继承、共享偏移、信号处置全部与 GNU 一致。
细读见 执行模型:零 fork 三层,哪里快哪里持平见
性能特征与 基准页。
兼容台账与 vendored 源码方法论
语义判定的一手依据是仓内 vendored 的 GNU bash-5.3 源码(third_party/bash):
每个行为主张必须给 file:line 坐标,WSL 里的 GNU 5.3.0 只做行为验证;
GPL 代码零拷贝红线与贡献者规则成文于 docs/PROVENANCE.md,
发布包不携带 third_party(crates.io 包从 15.6 MB 瘦到 8.9 MB)。
台账本身见 兼容总览:83/83 是什么意思;
超出 GNU 套件的部分——modernish 166/166、ble.sh 29601 行 rc=0、
git 测试框架 t/test-lib.sh 端到端可跑——同样钉成 CI 夹具。
实测数字
每条为真机实测、可复现;数组写的「快 N 倍」均对旧版引擎,对 GNU 的差距另列——输赢都展示。
| 指标 | rubash | 口径 / 对照 | 来源 |
|---|---|---|---|
| GNU Bash 上游语料 | 83/83 套通过,82 套逐字节一致 | 唯一残差 = GNU 自身 coproc 竞态 | rubash README:17 · 2026-10-12 全量重跑 |
| nvm.sh 解析(重词法) | 与 GNU 差距 720x → 8x(重词法字节 −40%) | 工程进度口径:差距收敛,非「快 8x」 | rubash PR #486(issue #281) |
| 关联数组元素写 K=5000 | O(n²)→O(1),单次写快 45 倍 | 对 GNU 差距 445x → 9.9x | rubash PR #650(issue #618) |
| 索引数组覆盖写 K=5000 | 快 177 倍 | 对 GNU 差距 674x → 3.8x;顺带修 O(n²) tokenizer(10001 段 563ms→17.8ms) | rubash PR #652(issue #616) |
| 单次 spawn 成本 | rubash 1.183 ms | GNU 1.121 ms——持平(Win32 CreateProcess 地板,如实展示) | unix-spawn-cost-20261012.md(min-of-3) |
更新动态
| 版本 | 日期 | 摘要 |
|---|---|---|
Unreleased(开发中) | — | 函数级 profiler(#815)、标量赋值快路径切片(#609)、set -E ERR-trap 嵌套语义与活动控制台 read 三面对齐(#720/#806)、多项热路径去分配优化。 |
1.4.0 | 2026-10-10 | 登录 shell 启动链、真 readline REPL、GNU cp 移植、stty 内建;83 套差异 3427 → 2072 行(−40%);crates.io 打包瘦身(15.6 MB → 8.9 MB)。 |
0.3.0 | 2026-08-22 | 兼容性归因账本发布(区分真实差异 / 宿主 fixture / 历史 runner 期望);复合语句前缀 alias 修复;进程替换回归覆盖扩充;tag 触发自动 Release。 |
取自 changelogs.json(rubash 仓 CHANGELOG.md)最新 3 个条目;完整流水见 更新日志。
相关链接
站内
- niubash 产品文档——rubash 的第一个完整宿主(参考集成)
- 执行模型:零 fork 三层 · 兼容总览:83/83 · 性能特征
- 基准页(8/8 全部快于 Git Bash 的同场对测)· 更新日志
站外
常见问题
rubash 和 niubash 是什么关系?
rubash 是 niubash 的语言引擎——bash 语法由它执行;同时它可独立使用:已上架 crates.io(1.4.0,cargo add rubash),是一个可嵌入的 GNU Bash 5.3 兼容引擎。
怎么把 rubash 嵌入到自己的程序里?
cargo add rubash 即作依赖使用。稳定嵌入 API 与四层 workspace 拆分(core/driver/interactive/facade)是 1.5.0 的目标,设计稿已合并(PR rubash#814),846 处 env-IPC 将迁为 typed bridges。
rubash 的内建命令覆盖多少?
GNU Bash 5.3 的 61 个内建全覆盖 + 扩展 env(62 个);另有 12 个高频文件命令内联执行与管道内联臂——echo | cat 这类管道全程零进程创建。
「83/83 GNU 套件」是什么意思?
GNU Bash 上游自带的 83 套测试语料在真机 Windows 上全部通过,其中 82 套输出与 GNU Bash 5.3 逐字节一致;唯一残差(nameref 1 行)被逐字节证明是 GNU 自身的 coproc 回收竞态。兼容性是测出来的:另有 2,686 个真实生态仓 / 9,701 个资产每夜巡检。
性能怎么样?
一次性执行(niu -c true)经专项优化后 19.8ms;niu-git 启动约 14ms(Git Bash 45–103ms);命令替换与子壳类负载比 GNU bash 快 13–62x。全部数字附实测方法与复现产物,见「基准测试」(/benchmarks/)。