Rust 实现的 Windows 原生 POSIX bash 执行器:给 DSH 提供一个真正原生的 bash不依赖…
36/100
综合分
9
GitHub 星标
446
npm 周下载
—/5
用户评分
数据截至 2026/10/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-bash-nativenpm 源 · dsh-bash-native 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · security
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-bash-native @ 0.3.1
✓Node 引擎要求 >=22.12.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/28 02:53:04
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 34 处,展示前 34 条)
- 读取本地文件lib/index.js:33
return statSync(path).isFile(); - 读取本地文件lib/index.js:55
return readdirSync(path, { withFileTypes: true }) - 读取本地文件lib/index.js:213
existing = readFileSync(file, 'utf8'); - 写入本地文件lib/index.js:221
mkdirSync(dirname(file), { recursive: true }); - 写入本地文件lib/index.js:222
writeFileSync(file, contents); - 读取本地文件lib/index.js:305
const digest = createHash('sha256').update(readFileSync(engine.path)).digest('hex'); - 读取本地文件lib/artifact.js:221
return statSync(path).isFile(); - 读取本地文件lib/artifact.js:227
readText: (path) => readFileSync(path, 'utf8'), - 读取本地文件lib/artifact.js:230
const stats = statSync(path); - 读取本地文件lib/artifact.js:237
sha256: (path) => createHash('sha256').update(readFileSync(path)).digest('hex'), - 写入本地文件lib/artifact.js:239
mkdirSync(path, { recursive: true }); - 写入本地文件lib/artifact.js:241
writeText: (path, text) => writeFileSync(path, text), - 读取本地文件lib/shim.js:108
const stats = statSync(path); - 写入本地文件lib/shim.js:116
copy: (from, to) => copyFileSync(from, to), - 写入本地文件lib/shim.js:118
mkdirSync(path, { recursive: true }); - 读取本地文件lib/toolchain-artifact.js:284
return statSync(path).isFile(); - 读取本地文件lib/toolchain-artifact.js:290
readText: (path) => readFileSync(path, 'utf8'), - 读取本地文件lib/toolchain-artifact.js:293
const stats = statSync(path); - 读取本地文件lib/toolchain-artifact.js:300
sha256: (path) => createHash('sha256').update(readFileSync(path)).digest('hex'), - 写入本地文件lib/toolchain-artifact.js:301
copy: (from, to) => copyFileSync(from, to), - 写入本地文件lib/toolchain-artifact.js:304
mkdirSync(path, { recursive: true }); - 删除本地文件递归lib/toolchain-artifact.js:307
rmSync(path, { recursive: true, force: true }); - 写入本地文件lib/toolchain-artifact.js:309
writeText: (path, text) => writeFileSync(path, text), - 读取本地文件lib/toolchain-artifact.js:312
return readdirSync(path); - 执行外部命令来自配置/变量lib/verify.js:226
result = spawnSync(path, [...args], { stdio: capture.stdio, timeout: 10_000, windowsHide: true }); - 读取本地文件lib/verify.js:234
const text = `${readFileSync(stdoutPath, 'utf8')}${readFileSync(stderrPath, 'utf8')}`.trim(); - 删除本地文件递归lib/verify.js:245
rmSync(directory, { recursive: true, force: true }); - 读取本地文件lib/preset-source.js:115
text = await readFile(path, 'utf8'); - 读取本地文件lib/state.js:34
return lstatSync(path).isDirectory() && !lstatSync(path).isSymbolicLink(); - 读取本地文件lib/state.js:42
return readdirSync(path, { withFileTypes: true }).map((entry) => ({ - 读取本地文件lib/state.js:57
const found = lstatSync(path); - 删除本地文件递归lib/state.js:68
remove: (path) => rmSync(path, { recursive: true, force: true }), - 读取本地文件lib/state.js:92
const lock = JSON.parse(readFileSync(join(packageRoot, 'engine.lock.json'), 'utf8')); - 读取本地文件lib/state.js:103
const text = readFileSync(join(packageRoot, 'toolchain', 'win32-x64', 'manifest.json'), 'utf8');
扫描于 2026/11/2(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-bash-local@deepseek-ai/dsh-sandbox@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-jobs-local@deepseek-ai/dsh-sandbox-local@deepseek-ai/dsh-sandbox-policy@deepseek-ai/dsh-shell@deepseek-ai/dsh-shell-env@deepseek-ai/dsh-subprocess@deepseek-ai/dsh-subprocess-local@deepseek-ai/dsh-system-prompt给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
2 张 · 点击查看大图功能亮点
- 不依赖WSL或MSYS
- 支持三档权限策略
- 后台作业
Rust 实现的 Windows 原生 POSIX bash 执行器:给 DSH 提供一个真正的 bash(brush 引擎,不依赖 WSL 或 MSYS兼容层),支持 DSH 的三档权限策略、后台作业和一节模型可见的环境契约
README
由 DeepSeek 最新模型翻译生成🐚 dsh-bash-native
Rust 实现的 Windows 原生 POSIX bash 执行器
给 DSH 的 shell 提供一个真正原生的 bash —— rubash 引擎,不依赖 WSL,也不需要 MSYS 兼容层
适配三档权限策略 · 后台作业 · 支持持久化终端
Listed on dsh-plugin.org
中文 · English
🐟 为什么需要它
避免肥鱼被 cmd 咬,也规避了子系统和 MSYS 兼容层的性能开销
0.3.1:引擎由brush更换为rubash,修复多项已知缺陷,提供更好的原生 POSIX 兼容
方案命令在哪里执行每条命令的代价
Git for Windows
MSYS2 兼容层上的移植 bash,POSIX 语义由运行时模拟兼容层每次起子 shell 或外部命令都要完整 fork 一个 MSYS2 进程(挂起线程、另起进程、经管道搬运内存),开销随子 shell 启动频率线性放大
WSL
命令在 Linux VM 的发行版里执行每条命令都要经 Windows/Linux 边界往返一次,延迟对高频短命令尤为不利
本插件rubash 引擎 + 工具链纯 Rust 实现的原生二进制,无模拟层、无 VM grep、sed、awk 等来自随包工具链,其余由引擎在进程内处理,没有兼容层或 VM 边界
展开完整文档(README 剩余 1 节)
🐚 dsh-bash-native
Rust 实现的 Windows 原生 POSIX bash 执行器
给 DSH 的 shell 提供一个真正原生的 bash —— rubash 引擎,不依赖 WSL,也不需要 MSYS 兼容层
适配三档权限策略 · 后台作业 · 支持持久化终端
Listed on dsh-plugin.org
中文 · English
🐟 为什么需要它
避免肥鱼被 cmd 咬,也规避了子系统和 MSYS 兼容层的性能开销
0.3.1:引擎由brush更换为rubash,修复多项已知缺陷,提供更好的原生 POSIX 兼容
方案命令在哪里执行每条命令的代价
Git for Windows
MSYS2 兼容层上的移植 bash,POSIX 语义由运行时模拟兼容层每次起子 shell 或外部命令都要完整 fork 一个 MSYS2 进程(挂起线程、另起进程、经管道搬运内存),开销随子 shell 启动频率线性放大
WSL
命令在 Linux VM 的发行版里执行每条命令都要经 Windows/Linux 边界往返一次,延迟对高频短命令尤为不利
本插件rubash 引擎 + 工具链纯 Rust 实现的原生二进制,无模拟层、无 VM grep、sed、awk 等来自随包工具链,其余由引擎在进程内处理,没有兼容层或 VM 边界
⚡ 实测:启动与子 shell 的代价
同一台机器(Windows 11 / x64)上的同一组脚本,每项取 5 次最小值,负载只用 shell 内建与一次外部进程,排除工具链差异。
复现:仓库里的 node scripts/bench-engines.mjs。
| 工作负载 | rubash(本插件) | Git Bash / MSYS2 |
| bash -c :(启动到退出) | 7 ms | 25 ms |
| echo hi | 6 ms | 26 ms |
| 算术循环 10k 次 | 65 ms | 75 ms |
| [ ] 判定 20k 次 | 167 ms | 181 ms |
| 命令替换 300 次 | 11 ms | 3052 ms |
| 子 shell 300 次 | 25 ms | 2497 ms |
| 外部进程 20 次(cmd /c exit) | 192 ms | 560 ms |
差距来自 fork:MSYS2 每次命令替换与子 shell 都要 fork 一个兼容层进程(约 8–10 ms),rubash 两样都做在进程内(每次约 0.04 ms),300 次就相差 2–3 秒。
🧭 路径不会被“自动替换”
Git Bash / MSYS2 把参数交给原生程序时会猜哪些像路径并改写(/flag → C:/Program Files/Git/flag,于是脚本和 agent 被迫记着 MSYS_NO_PATHCONV=1);连数据位也一起改:用 MSYS 调原生 awk.exe 跑 awk '/x/{print}',程序位到手是 X:/{print},直接语法错误、进错路径。
rubash 不猜:按子进程方言,整条 argv 要么原样交给带 POSIX 层的程序,要么统一翻成 Win32 拼写;随包工具的脚本、模式、程序位永不改写,极大减少了找不到路径的情况。
📦 安装
CLI 安装
以 web profile 为例
dsh plugin --profile web add dsh-bash-native
dsh 网页版 / 桌面版安装
dsh 插件页面 → 右上角 添加插件 → 填入插件名 dsh-bash-native 或仓库地址:
https://github.com/SpookyWaste/dsh-bash-native
重启后,在 Settings → General 里把 Native Bash (Windows) 设为默认 preset(或在会话里切过去)。
持久化终端组件默认关闭,在插件管理中可以打开。见持久终端组件。
平台 Windows x64
DSH
=0.2.0-rc.2 <0.3.0-0(0.2.0-rc.2 - 0.2.1-rc.3实测)
持久终端组件需要 DSH >=0.2.1-alpha.1才能开启
⚙️ 引擎
引擎是 rubash(unixwin/rubash,Rust 写的 bash 5.3 兼容 shell,MIT),本仓库从源码构建它、按 engine.lock.json 里的 commit 应用三笔补丁,产物 engine/win32-x64/rubash.exe(约 11 MB)随包提交。
兼容 MSYS 的 uname -s 身份(MSYS_NT-…),所以脚本里按 MSYS 分支的逻辑也能成立;并发、取消与作业语义由引擎自己实现,跟 MSYS 运行时无关。
🧩 补丁清单(点击展开)
补丁做了什么
0001-data-primary-positions-every-child
“数据位”的判定从 POSIX-aware 子进程推广到所有子进程:grep/sed/awk 的模式、脚本与程序文本,find 的模式主项,basename/dirname 的位置参数都原样交给程序;文件操作数照常翻成 Windows 形态。
0002-drop-undecodable-environment-entries
启动时丢掉 Win32 能传入、但 Unicode 表示不了的环境项(std::env::vars() 遇到它会 panic);代价是那一条变量,而不是每条命令都在建 shell 时 abort。
0003-file-commands-from-path
新增 RUBASH_FILE_COMMANDS_FROM_PATH:由 shell 指定哪些「进程内文件命令」改从 PATH 上的程序执行(all / none / 名字列表),并从 shell 自己的变量表读取,所以 --rcfile 也能设置;顺带让内联管道分支不再无视宿主的「关掉进程内副本」开关。
💡 每次解析都按 lock 里的 sha256 校验产物,并按盖章跳过重复校验:产物的 size 与 mtime 记进 %LOCALAPPDATA%\dsh-bash-native\verified\,没变就不再读那 11 MB(verifyArtifacts: 'always' 可恢复每次都哈希)。
🔧 实现
- 注册 ctx.shell:ShellExecutor 的 Service Provider,构建在 @deepseek-ai/dsh-bash-local 之上,每条命令交给解析到的 rubash 引擎;引擎与工具链都随包分发,并在解析时按 lock 与 manifest 校验。
- 服从 DSH 的三档文件策略(read-only / workspace-write / danger-full-access):受限档位把引擎 argv 交给 ctx.sandbox,不限档位直接 spawn 并如实报告档位。
- 后台作业经 ctx.jobs 汇报,超出内存上限的输出落到 spill 文件、路径随结果返回;echo、cat、sort 等空 PATH 也能跑,因为随包工具链先于宿主 PATH。
- Web 面用自带的 agent preset 挂载,agent 面用 overlay 显式启用;它不替换宿主层的 ctx.shell,因此其他 preset 的 pwsh 工具不受影响。
🎛 两个预设0.2.0:静态挂载改为跟随官方预设替换
cordis.patch.yml 只有一行注册器(dsh-bash-native/presets),两个 preset 由插件在运行时注册:启动时读本机安装的 presets/{standard,minimal}.patch.yml,把 shipped 的 shell 面换成插件自己的 realm group;它们各自带一个 isolate: { shell: true, terminals: true } 的 realm,宿主层与其他 preset(包括用 pwsh 的那些)不受影响。
预设挂载什么什么时候选
Native Bash (Windows)id bash-native,order 5 读本机 harness 那条线的 standard,只换 shell 面:每次调用都是全新的 bash,文件、作业、委派等全套工具跟着那一版上游走日常使用
Native Bash (Windows, minimal)id bash-native-minimal,order 6 读本机那条线的 minimal,只换 shell 面:一个 persona 与一个持久 bash。
只要一个 shell 的轻量会话
📟 持久终端组件
插件页面里 dsh-bash-native 提供两个可分别开关的组件:dsh-bash-native/presets(两个预设,默认开)与 dsh-bash-native/terminal(提供 6 个交互式持久终端工具,默认关)。
该组件和内置的 持久终端(@deepseek-ai/dsh-experimental-terminal-bundle)注册同名工具,不能也不需要同时开启。 (tool "terminal_open" is already registered)
🛠 配置
除下表外,执行预算继承自 @deepseek-ai/dsh-bash-local:cwd、timeoutMs、maxTimeoutMs、maxOutputBytes、maxSpillBytes、graceMs,默认值与上限由那一侧的 schema 单一出处提供。
键默认含义
confine
true
是否服从 ctx.sandbox;关闭即放弃文件策略与拒绝标记
requireEngineOnLoad
false
无引擎时是加载失败,还是每次调用失败(两个预设都设 true)
toolsDir
''
POSIX 工具链目录;空 = 先看每用户目录里自建的那份(%LOCALAPPDATA%\dsh-bash-native\tools\bin),没有程序就用随包工具链。填了则照用,空目录也算数(不会悄悄换成随包那份)
fileCommandsFromPath
['sed','rmdir']
改从工具链程序执行的引擎内建文件命令(仅限引擎实现的 12 个名字);工具链没有提供该程序、或工具链目录不在 PATH 上时自动忽略,进程内副本继续生效。见下面的「已知限制」
rcFile
''
持久 PTY 会话读的启动文件;空 = %LOCALAPPDATA%\dsh-bash-native\bash-native-rc.sh
denialSignatureAdditions
['os error 5']
追加的拒绝签名,默认值让非英文 Windows 也标得出拒绝
shellEnvOverrides
{}
追加环境变量,层叠在模型友好默认值之上
verifyArtifacts
'stamped'
校验力度:stamped 只在产物或运行副本的 size/mtime 变化时重新哈希;always 每次解析都哈希(引擎 11 MB、工具链 37 MB)
🧰 工具链
工具链随包分发,装完即用。
📚 101 个名字,公布其中 20 个
| 类别 | 内容 |
| 公布(20) | grep、sed、awk、jq、find、xargs、diff、cmp、which、timeout、stat、ps,以及 tty、nohup、nice、uptime、hostid、pathchk、locate、updatedb |
| 只装不公布(81) | uutils coreutils 的 88 个程序(cat、ls、rm、cp、head、tail、wc、sort、seq 等——引擎不再自带这些),以及 shell 内建要用的程序形态 echo、printf、pwd、test、true、false、kill |
- 支持与引擎相同的 /tmp 与盘符别名,「程序再启动程序」的链同样成立:printf '/tmp/f\n' | xargs awk '{print}' 与 printf '/tmp/x\n' | xargs rm 都拿到真实路径。
- 数据位由两边同一张表保护:开关 -e/-f 的值、grep/sed/awk 的首个位置操作数、find 的 -name/-path 类主项、basename/dirname 的位置参数,都不翻译——引擎启动的子进程与工具链里「程序再启动程序」的那一半用的是同一份清单。
- 顺带把 bash 与 sh 放到 PATH 上(工具链目录在前,名字目录紧随其后,两者都排在宿主原有 PATH 之前):
src/shim.ts 在 %LOCALAPPDATA%\dsh-bash-native\shim\<引擎 sha256>\ 里把这两个名字指向已校验引擎——同卷时是硬链接,两个名字共用引擎那一份字节。
⚠️ 已知限制
- 两条与进程内副本无关的平台差异:
| 形态 | 实测 |
| cd /absent 2>err.txt \| cat | 诊断既不在 err.txt 也不在 shell 的 stderr 上 |
| printf … \| head -c 1 的 PIPESTATUS[0] | 内建写端不报断管,0 而不是 141 |
- 断管(读端提前关闭)时,工具与外部程序用它们自己的措辞和退出码——这是 Windows 没有 SIGPIPE 的后果(每个工具各自决定断管怎么办):
| 命令 | 写端退出码 | 备注 |
| seq 1 200000 \| head -c 1 | 0 | stderr 打 write error: Broken pipe |
| yes \| head -c 1 | 0 | 不吭声 |
| cat big \| head -c 1 | 13 | — |
| ls -R 某目录 \| head -c 1 | 1 | — |
| 引擎自己的内建 | 0 | 不报断管(见上一条 PIPESTATUS[0]) |
- { …; } | head 在单行超过约 100 KB 时会挂起(rubash 1.4.3,实测:60 KB 单行正常、200 KB 单行超时):读端读走一部分就退出,写端不中止;把这条管道的输出接到文件时是挂起,接到另一个管道时则整段输出丢失。绕开办法:{ …; } | cat | head,或先写到文件再读。记录在 docs/research.md §72,test/test-brush-regressions.mjs 每次运行都会打印现状。
- 不认识的程序分不清数据与路径:把一个「像路径」的数据词交给引擎不认识的原生程序(node -e '…' '/x/{print}'),它会被当作路径操作数翻成 Win32 拼写——MSYS 同样如此;区别是随包工具的脚本、模式、程序位有确定的数据位表,永不被改写。
🧹 磁盘足迹与清理
运行时状态都在 %LOCALAPPDATA%\dsh-bash-native 下,并且按内容寻址:每个引擎构建一个 shim/<引擎 sha256>/。
| 目录 | 谁写的 | 大小 | 删掉会怎样 |
| shim/<摘要>/ | 每次解析 | 引擎大小(同卷硬链接时约 0) | 下次解析重建 |
| toolchain/<摘要>/ | 每次解析 | 约 36 MB(同卷硬链接时约 0) | 下次解析重建 |
| verified/ | 每次校验 | 几十 KB | 只会多一次哈希 |
显式清理(停掉 DSH 之后运行):将<dsh_profile>替换为你的profile路径,例如:%USERPROFILE%\.dsh\profiles\<profile>
node <dsh_profile>/node_modules/dsh-bash-native/bin/clean-state.mjs # 只报告,不动文件
node <dsh_profile>/node_modules/dsh-bash-native/bin/clean-state.mjs --yes # 删掉被取代的 shim/ 与 toolchain/ 缓存
📄 许可
| 内容 | 许可 | 声明与扫描 |
| 本插件 | MIT | LICENSE |
| rubash 引擎 | MIT | engine/LICENSE.rubash、依赖扫描 engine/THIRD-PARTY.md |
| 随包工具链 | MIT | uutils coreutils/findutils/grep/sed、jaq、goawk、仓库内 posix-extra;toolchain/LICENSES/ 与 toolchain/THIRD-PARTY.md |
🙏 参考与致谢
为智能体提供原生 bash 这条路上,oh-my-pi 是最早的先行实现之一,本插件早期针对 brush 的诊断与修法也受益于它留下的记录。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
SpookyWaste/dsh-bash-native
Rust 实现的 Windows 原生 POSIX bash 执行器:给 DSH 提供一个真正原生的 bash不依赖…
相关插件 · 安全 / 权限
智能体逆向工程morluto/rea
用智能体逆向工程任何东西,从应用行为到原生二进制。
★ 415,267已汉化DSH
73.3
智能体集群框架ruvnet/ruflo
面向 Claude Code 与 Codex 的智能体元基座meta-harness。
★ 80,414已汉化MCP
71.9
WorkBuddy 模型接入corrinehu/dsh-workbuddy-connect
2026 年 10 月 20 日起,WorkBuddy…
★ 1,604已汉化DSH
71.7
破甲一键通z91772524-ai/pojia-next
十五个 AI…
★ 967已汉化DSH
71.6
AI 代理虚拟终端strukto-ai/mirage
Mirage 是给 AI 智能体用的虚拟终端:一层 shell,统管数据、命令行和运行时。Unix…
★ 3,756已汉化DSH
70.8
Agent 操作层agentic-os-org/ANOLISA
ANOLISA(Agentic Nexus Operating Layer & Interface System Architecture)|智能体操作系统,带运行时、安全、可观测性,以及 Tokenless 响应压缩,降低 token 用量与成本。
★ 649已汉化DSH
70.7