@everruns/bashkit-wasm

中文文档
0.21.0发布于 2026/11/11MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 4.4万

浏览器 (WebAssembly) 的 sandboxed bash 解释器 。 单行本——无共享箭头缓冲器,无COOP/COEP头.

中文使用文档
文档目录18 节
  1. 现场演示
  2. 安装
  3. 快开始
  4. 平面 <script type="module"> (没有捆绑)
  5. Async 自定义内建
  6. 同步 vs 同步
  7. 交互式终端
  8. 选项
  9. 虚拟文件系统
  10. 分析、取消和持久性
  11. 主机支持的文件系统
  12. 包括什么
  13. 限制
  14. 实例
  15. 发展
  16. 许可证
  17. 部署和冷却启动
  18. 可选 Python/ TypeScript 和主机函数

@everruns/bashkit-wasm (英语)

Sandboxed bash 解译器编译到WebAssembly,用于 浏览器和任意 其他 JavaScript 运行时间:边缘工人/无服务工人(云雾工人,Vercel) 边缘、德诺部署、节点、德诺和邦.

与WASI线程构建不同,这个包是 单行: 需要没有 SharedArrayBuffer 财务报告和审定财务报表 无跨源隔离 (单位:千美元)COOP编号 :COEP)头. 包括嵌入式和第三方 iframe 无法设置这些信头的上下文, 以及限制的边缘 无法使用线程的运行时间 .

这是一个 wasm-bindgen 模块,所以它运行 在任何JS主机,但 没有 (单位:千美元) 非JS/WASI运行时间(wasmtime, (中文(简体) ), wasmer) (中文(简体) ). 用于本地节点.js / Bun / Deno 加通( 较快, 无相机), 使用 @everruns/bashkit 改为:; 当本地加通无法加载、浏览器和边缘时, 访问此软件包 运行时间.

现场演示

在这个软件包上搭建了一个完整的交互式终端, examples/browser。 。 。 . 单曲 index.html 维特: pnpm install && pnpm start,没有建设步骤 并且没有特别的标题.

Bashkit browser terminal

安装

npm install @everruns/bashkit-wasm

快开始

import { initBashkit, Bash } from "@everruns/bashkit-wasm";

// Load the .wasm once before constructing Bash.
await initBashkit();

const bash = new Bash();
const result = bash.executeSync('echo "Hello, browser!" | tr a-z A-Z');
console.log(result.stdout); // HELLO, BROWSER!

平面 <script type="module"> (没有捆绑)

<script type="module">
  import { initBashkit, Bash } from "https://esm.sh/@everruns/bashkit-wasm";
  await initBashkit();
  const bash = new Bash();
  document.body.textContent = bash.executeSync("seq 1 5 | paste -sd+ | bc").stdout;
</script>

Async 自定义内建

将JS召回登记为bash命令。 Async召回(例如: fetch / 图QL 请求) execute(),Aync API : (中文(简体) )

const bash = new Bash({
  customBuiltins: {
    graphql: async (ctx) => {
      const res = await fetch("/graphql", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: ctx.stdin ?? "{}",
      });
      return await res.text();
    },
  },
});

const out = await bash.execute('echo "{ me { id } }" | graphql | jq .data');
console.log(out.stdout);

ctx 实值 { name, argv, stdin, env, cwd, fs }。将内建的 stdout作为一个 字符串(或 Promise<string>; 抛出以退出码 1 成为 stderr.

ctx.fs 是一个活柄 不变 脚本看到的虚拟文件系统, 所以 a 内建可读取输入并写入以后命令取取的输出 :

const bash = new Bash({
  customBuiltins: {
    "uppercase-file": (ctx) => {
      const text = ctx.fs.readFile(ctx.argv[0]);
      ctx.fs.writeFile("/out.txt", text.toUpperCase());
      return "done\n";
    },
  },
});
bash.writeFile("/in.txt", "hello\n");
await bash.execute("uppercase-file /in.txt && cat /out.txt"); // -> HELLO

ctx.fs 已经 readFile, (中文(简体) ), writeFile, (中文(简体) ), appendFile他们的二进制安全 *FileBytes 变体, exists, (中文(简体) ), mkdir, (中文(简体) ), remove,以及 ls,同样的表面 作为 Bash 下面的VFS助手.

同步 vs 同步

  • executeSync(cmd),为直击和 jq返回一个 ExecResult 直接说 脚本暂停时抛出, 例如 sleep 或自动同步 习惯内置.
  • execute(cmd)返回 Promise<ExecResult>同步时需要 自定义内置或墙钟操作可能运行.
  • executeWithOutput(cmd, callback),同步执行加递增 (stdout, stderr) 块. 回来的 ExecResult 仍然具有权威性.

交互式终端

Terminal 在模拟终端上运行交互式 shell 会话: 您 前键键键, 它会返回像 : x 任期.js。 。 。 . vi, (中文(简体) ), less 财务报告和审定财务报表 more 运行全屏。 试试看 编辑 bashkit.sh 游乐场。 。 。 .

import { Terminal as XTerm } from "@xterm/xterm";
import { initBashkit, Terminal } from "@everruns/bashkit-wasm";

await initBashkit();
const xterm = new XTerm();
xterm.open(document.getElementById("term"));

const term = new Terminal({ rows: xterm.rows, cols: xterm.cols, cwd: "/home/user" });
let running = false;
let again = false;
async function pump() {
  if (running) return void (again = true);
  running = true;
  do {
    again = false;
    await term.runUntilIdle(); // { status: "idle" } or { status: "exited", exitCode }
    xterm.write(term.takeOutput());
  } while (again);
  running = false;
}
xterm.onData((keys) => { term.send(keys); pump(); });
xterm.onResize(({ rows, cols }) => term.resize(rows, cols));
pump();

runUntilIdle() 当会话等待输入时解决; 键中键已发送 在命令运行中排队. screenText() 返回可见屏幕为 纯文本和 fs() 读什么 vi 已保存 . Terminal 将每个 Bash 选项加 rows 财务报告和审定财务报表 cols这是 undefined 在自定义建筑中 BASHKIT_WASM_FEATURES=""见 终端指南 对于行编辑器, vi 键和限制.

选项

new Bash({
  username, hostname, cwd,
  env: { KEY: "value" },
  maxCommands, maxLoopIterations, maxMemory,
  files: { "/config.json": '{"debug":true}' },
  customBuiltins: { name: (ctx) => "..." },
  fs: hostFileSystem, // host-backed filesystem; see below
});

虚拟文件系统

通过帮助创建的文件可见脚本,反之亦然:

bash.mkdir("/data");
bash.writeFile("/data/x.txt", "hi\n");
bash.appendFile("/data/x.txt", "there\n");
bash.readFile("/data/x.txt"); // "hi\nthere\n"
bash.exists("/data/x.txt");   // true
bash.ls("/data");             // ["x.txt"]
bash.executeSync("cat /data/x.txt").stdout; // "hi\nthere\n"
bash.remove("/data/x.txt");

// Binary-safe I/O avoids UTF-8 conversion.
bash.writeFileBytes("/data/blob", Uint8Array.from([0, 255]));
bash.readFileBytes("/data/blob");

// bash.fs() returns the same live handle passed to builtins as ctx.fs
const fs = bash.fs();

分析、取消和持久性

analyze(script) 提供与2004年相同的守门员预测 本地装订。 处理解析错误或 isOpaque 作为否定/即时,不安全:

const analysis = bash.analyze("cat input.txt | jq . > output.json");
if (analysis.isOpaque) throw new Error("permission prompt required");

cancel() 在命令边界上设置粘性合作旗帜; clearCancel() 使实例可以重新使用. commit() 返回 a 内容地址对象集和 checkout(id, objects, policy?) 恢复:

const saved = bash.commit();
const resumed = new Bash();
resumed.checkout(saved.id, saved.objects); // policy defaults to "superset"

主机支持的文件系统

过 fs 来直接运行脚本,以对抗您拥有的存储,一个持久对象,一个 OPFS handle, IndexedDB,取而代之的是内相VFS. 没有复制到或 diffed back out:运行期间的每个读写都是对对象的调用.

const bash = new Bash({ cwd: "/workspace", fs: myHost });
const r = await bash.execute("grep -rl TODO . | head -5");

实施7个所需方法;每个方法可直接或作为 Promise数字 :

read(path)                 // -> Uint8Array | string   (throw ENOENT when absent)
write(path, bytes)         // -> void
mkdir(path, recursive)     // -> void
remove(path, recursive)    // -> void
stat(path)                 // -> { type: "file" | "dir" | "symlink", size?, mode?, mtimeMs? }
readDir(path)              // -> [{ name, type, size?, mode?, mtimeMs? }]
exists(path)               // -> boolean

append, (中文(简体) ), copy, (中文(简体) ), rename,以及 chmod 是可选的:省略它们,它们是 由所需原始物合成(chmod 被接受和忽略,所以 chmod +x 仍可工作). symlink 财务报告和审定财务报表 readLink 也可以选择,但脚本 无法到达他们 ENOSYS 当宿主忘记他们的时候.

您的主机只执行原始存储, POSIX 语义( 父目录) 检查,"是目录",同位素解析)被执行在其上方. 扔一个 Error 携带 code (单位:千美元)ENOENT, (中文(简体) ), EEXIST, (中文(简体) ), EACCES, (中文(简体) ), EPERM, (中文(简体) ), EISDIR, (中文(简体) ), ENOTDIR, (中文(简体) ), ENOTEMPTY, (中文(简体) ), EXDEV, (中文(简体) ), ENOSYS所以,击打报告失败的方式 真实的外壳.

两份合同说明:

  • execute() 只有这个. 主机呼叫可以暂停口译,而且 executeSync 它不能等待,它报告中止而不是封锁. 同步 bash.readFile(...) 帮助者的行为也一样.
  • files 与 fs。 。 。 . 种子通过 VFS 写入 同步的, 一个承诺返回的宿主永远无法满足。 写入种子 数据直接通过主机.

提供 /dev/null 如果您的脚本重定向到主机中; 带有主机 文件系统下面没有内置的 VFS 来提供它 .

包括什么

平面击打加内置的文本工具(grep, (中文(简体) ), sed, (中文(简体) ), awk, (中文(简体) ), jq, (中文(简体) ), find, (中文(简体) ), (......)和(......) jq。不包括在浏览器构建中: 输出 HTTP (curl编号 :wget, (中文(简体) ), ssh 财务报告和审定财务报表 sqlite,这些需要套接字、线程或主机 文件系统浏览器沙盒不提供。 通向网络的桥梁 自定义内置( 见上文) 因此请求要通过您的应用程序 fetch。 。 。 .

限制

  • 取消是合作的. 主机定时器驱动 sleep, (中文(简体) ), timeout,以及 配置执行期限 。 同步 CPU 循环无法观察到 JS 回调或 cancel() 直到控制返回到事件循环,所以命令, 循环, 解析燃料, 和内存限制 仍然是这种工作的硬约束 .
  • executeSync 无法运行 aync 内建. 单条事件循环 不能解决一个 Promise 而不产生; 内建于 executeSync 快速失败 。 使用 execute()。 。 。 .

实例

  • examples/browser ,上面显示的完整交互式终端,在Vite上(没有建设步骤,没有标题).
  • 最小、无依赖性演示 example/,交互式 终端和一个合成已建/ctx.fs 演示, 由任何静态文件服务器服务 . 见 example/README.md。 。 。 .

发展

# Build the bundle and run the headless integration tests:
bash scripts/build.sh
node --test "__test__/*.test.mjs"
# or, from the repo root:
just build-wasm

许可证

麻省理工学院 巴什基特语Name 项目.

部署和冷却启动

服务 bashkit_wasm_bg.wasm 作为 application/wasm 与 Brotli 或 gzip HTTP 连接 压缩. Raw npm 文件大小不是传输大小 。 使用含有内容的资产 URL 有长生不老的卡通; 保持JS胶水和WASM 从相同的 一起建设. initBashkit() 使用 ham-bindgen 的流载器 服务器发送正确的 MIME 类型。 缓慢的移动连接可能要超过 15秒下载多兆字节捆绑,所以从中选择启动最后期限 您的应用程序的测量网络条件.

软件包包括 build-info.json:来源承诺,脏检查状态, 编译器/工具、货物简介/地物以及装运的WASM的SHA-256. 没有Git元数据的源文件记录了一个无效源身份. 来源 发行版之间的取出可与旧 npm 版本相同 释放; 比较源承诺和版本.

维护者可以运行受限相容性和压缩大小的门 :

node crates/bashkit-wasm/bench/compat.mjs
node crates/bashkit-wasm/bench/artifact.mjs crates/bashkit-wasm/pkg --check

这个 浏览器基准方法 描述可复制 冷启动和执行实验 和测量的剖面交易.

可选 Python/ TypeScript 和主机函数

导入 @everruns/bashkit-wasm/runtimes 用于运行时启用的单线 捆绑; 默认导入会保持微弱 。 启用 python编号 :typescript 明确 通过 externalFunctions编号 :externalHandler (P)或 typescriptExternalFunctions编号 :typescriptExternalHandler (编). 回调支持 JSON 值以及执行本地中止符号 。 使用同步 Bash.execute,每例执行一次。 见 主机函数指南。 。 。 .

构建两个变体 scripts/build.sh release,然后是 BASHKIT_WASM_VARIANT=runtimes BASHKIT_WASM_FEATURES=terminal,python,typescript scripts/build.sh release。 。 。 .

版本与发布记录

@everruns/bashkit-wasm 共发布 15 个版本,首次发布于 2026/07/19;过去 12 个月发布了 15 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.21.0latest2026/11/113 天前
0.20.32026/11/059 天前
0.20.22026/10/3114 天前
0.20.12026/10/3015 天前
0.19.02026/10/1629 天前
0.18.22026/09/231 个月前

关于 @everruns/bashkit-wasm 的常见问题

@everruns/bashkit-wasm 是什么?

浏览器 (WebAssembly) 的 sandboxed bash 解释器 。 单行本——无共享箭头缓冲器,无COOP/COEP头.

如何安装 @everruns/bashkit-wasm?

在项目目录运行 npm install @everruns/bashkit-wasm,或使用 pnpm add / yarn add / bun add。

@everruns/bashkit-wasm 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@everruns/bashkit-wasm 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@everruns/bashkit-wasm 可以商用吗?

@everruns/bashkit-wasm 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@everruns/bashkit-wasm 的下载量有多少?

根据 npm 官方下载统计,@everruns/bashkit-wasm 在 2026/10/14 – 2026/11/12 这 30 天内被下载 44,321 次,日均约 1,477 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@everruns/bashkit-wasm 还在维护吗?

最新版本 0.21.0 发布于 2026/11/11(3 天前);至今共发布 15 个版本,其中过去 12 个月发布了 15 个;首次发布于 2026/07/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。