For AI agents: the complete documentation index is available at https://a3s-lab.github.io/ash/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/ash/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/ash/guide/cli.md.
  • 简体中文
  • next
  • CLI 参考

    ash 的主要 CLI 是机器接口:成功输出和错误诊断都使用稳定的 ASON,不提供人类帮助页、 颜色或进度条。独立且受 feature 控制的 ash shell 入口明确面向人类,使用普通字节、 诊断与退出状态,而不是 ASON。

    命令输入输出
    ash --version稳定版本字符串
    ash --build-info版本、目标、协议、ASON、提交与信任指纹
    ash asonstdin 裸 ASON唯一规范 ASON
    ash runstdin 单个类型化请求单个最终响应
    ash rpcstdin/stdout 长度帧握手与有序响应帧
    ash shell [--no-profile | --profile FILE] [-c SOURCE | FILE]终端、内联、原生文件或有界 stdin人类命令输出与带源码位置的诊断
    ash self status [--prefix PATH]安装前缀当前/前一版本与安装状态
    ash self check --candidate FILE候选二进制健康、版本与目标
    ash self update [--prefix PATH] [--from DIR]签名元数据或离线目录激活结果
    ash self rollback [--prefix PATH]安装状态回滚或计划结果
    ash self recover [--prefix PATH]安装日志恢复结果

    ash self replace 是更新流程使用的内部 Windows 辅助入口,不是普通 Harness API。

    人类 Shell 检查点

    当前人类 Shell 检查点会在 stdin 为终端时打开跨平台行编辑 REPL,并针对同一份持久原生状态 顺序执行当前命令与管道语法。已实现 pwdecho(含 -n)、cd、展开后的 export/unsetset pipefail 控制、exit、可移植 ls、原始字节 cat、文本 grep、可移植 cp/mv/rm、只创建空文件的 touch、命名参数与上一状态展开、 嵌套命令替换、引用感知的路径名展开、宿主原生命令、Windows 上显式 WSL 命令,以及同一行 原生/WSL/可移植/状态管道、左结合的 &&/|| 条件列表,以及有序的原生、WSL、 可移植与状态重定向;源码也可以来自 -c SOURCE、原生 脚本文件路径或 stdin:

    ash shell
    ash shell -c "grep -in 'semantic' crates/ash-ops/src/semantic.rs"
    ash shell -c 'export NAME=world; echo "hello $NAME"; echo $?'
    ash shell -c "native:rustc --version"
    ash shell -c "linux:uname -a" # Windows + WSL
    ash shell -c 'native:rustc --version >version.txt 2>&1'
    ash shell -c 'cat - <input.bin >copy.bin'
    ash shell -c 'cp input.bin backup.bin; mv backup.bin archive.bin'
    ash shell -c 'grep -F ready status.txt && echo complete || echo pending'
    ash shell -c 'echo crates/*/Cargo.toml'
    ash shell ./script.ash
    printf 'echo from-stdin\n' | ash shell --no-profile
    ash shell --profile ./profile.ash

    文件、stdin 与 Profile 源码必须是有效 UTF-8,且不能超过 1 MiB;原生文件路径本身 不会转换为 UTF-8。以 - 开头的文件参数可写成 ash shell -- ./-script.ash。可移植 ls 最多 接受一个路径(默认 .),按稳定原生顺序每行输出一个名称,并支持 -a/--all-d/--directory-1、短选项组合与 --。可移植 cat 要求一个路径,原样输出 字节且不添加换行,接受 --,并共享 128 MiB 读取/捕获上限。在多阶段管道中, cat - 会消费上游字节流;独立命令可通过显式 < 文件提供 -。未重定向的独立 stdin -、选项与多个文件仍会明确失败。 可移植 grep 要求一个有效 UTF-8 的普通文件, 默认使用 Rust 正则表达式;支持 -E/--extended-regexp-F/--fixed-strings-i/--ignore-case-n/--line-number、短选项组合与 --。搜索上限为 64 MiB;无匹配时不输出诊断并返回状态 1。在多阶段管道中, grep PATTERN - 会用同一语义消费上游 UTF-8 流,输出上限为 128 MiB;独立命令也可通过 < 提供 -。目录、多个文件、未重定向的独立 stdin - 与不支持的选项都会明确失败。

    可移植 cp SOURCE DESTINATIONmv SOURCE DESTINATIONrm PATHtouch PATH 只接受这些精确普通文件参数数量和 --。持久 cwd 是它们的耐久事务 根。父路径穿越、逃逸、符号链接/reparse 穿越、目录、超过 128 MiB 的文件,以及无法 写入 UTF-8 日志的路径都会显式失败。复制、移动与 touch 都不覆盖;当前 touch 只 创建新的空文件,不更新已有文件时间戳。复制、移动和删除会在执行前立即派生 BLAKE3 源 preimage,再由与 ASH/1 fs 共用的事务重验。冲突不重试、返回状态 1,并保留外部 变化或已有目标。事务根下保留的 .ash 目录保存跨进程锁、回滚与重启恢复状态。

    启动 Profile 是显式选择的:--profile FILE 指定一个文件,非空 ASH_PROFILE 提供 配置默认值,--no-profile 则禁用两者。相对路径以 Shell 初始 cwd 为基准。Profile 会在执行任何命令前完整解析,因此语法错误不会应用前缀;非交互调用在带源码位置的 诊断后以状态 2 停止,交互调用则输出同一诊断并以安全模式打开。Profile 中的 cd 和导出环境等状态会延续到所选输入。

    提示符默认为 ash> ASH_PROMPT 可替换它,但必须是有效 UTF-8。在提示符处按 Ctrl+C 会把 $? 设为 130 并继续,EOF 则返回上一状态。exit [STATUS] 会停止当前 提交源码的剩余命令并退出 REPL;省略状态时复用 $?,显式值只能是 0 到 255 的 整数,非法参数返回 2 但不会退出。

    ASH_HISTORY 选择相对初始 cwd 的持久历史文件,空值会禁用持久化。类 Unix 主机 默认依次使用 $XDG_STATE_HOME/ash/history$HOME/.local/state/ash/history,Windows 使用 %LOCALAPPDATA%\ash\history。以空格或制表符开头的行不会记录。符号链接和非普通 文件目标会被拒绝,Unix 历史文件强制为 0600;路径不安全或不可用时会给出警告, 但内存中的行编辑会话仍可使用。

    export NAME=VALUEunset NAME 会持久更新 Shell 变量和导出环境。两者各接受一个 展开后的参数和 --;名称必须是 ASCII Shell 标识符,空值会被保留,移除不存在的 名称也会成功。可能含分隔符的值需要引用,例如 export COPY="$SOURCE"。列出环境与 多个名称尚未实现。

    set -o pipefail 会持久启用“最右失败阶段”管道状态,set +o pipefail 恢复默认的 最终阶段策略;其他 set 形式返回状态 2。启动 Profile 可以预先选择策略。放入管道 时,set 只操作该阶段的状态克隆,不会修改父 Shell 策略。

    $NAME${NAME}$? 会在每条命令解析执行目标前展开。Shell 变量优先于按宿主 规则查询的导出环境,未定义名称为空。单引号与转义后的美元符保持字面量;双引号保留 单个原生字段(包括空字段),未引用值则按固定 ASCII 空格、制表符与 LF 拆分,未引用 空展开可能移除整个词。当前检查点不使用 IFS 配置拆分;原生字符串单元会无损通过 展开和直接 argv 启动。

    嵌套 $(SOURCE) 命令替换会解析为同一份类型化 Script 计划,诊断保留顶层源码的 精确位置,嵌套上限为 32 层。命令词与文件重定向目标中的替换统一按源码顺序执行。 每次替换都会获得完整 ShellState 克隆,因此 cwd、变量、环境、选项、状态与 exit 只在内部生效;普通外部进程与文件系统副作用仍然可见,即使后续管道阶段的外层预检 失败也不会回滚。ash 捕获 stdout 并删除全部尾随 LF;双引号内保留单个字段和内部 换行,未引用时才按固定 ASCII 分隔符拆分。 内部非零状态不会覆盖父 $? 或阻止外层命令,stderr 与诊断只向外传播并渲染一次。 输出中的 NUL 会被拒绝;Unix 保留非 UTF-8 原生字节,Windows 则要求有效 UTF-8。 替换值、stdout 与 stderr 共享剩余的 128 MiB 同步额度;捕获失败会阻止外层命令 执行。短路管道完全不执行替换,且整份源码仍会在所有副作用前完整解析。

    固定的未引用字段拆分之后,路径名展开会在命令字段和重定向目标中识别活动的 *?[abc]、升序 [a-z],以及取反的 [!abc]/[^abc]。单引号、双引号与 反斜杠会保护操作符;未引用的参数或命令替换输出可以引入模式。相对模式从持久 cwd 枚举,绝对模式保持绝对路径;匹配区分大小写,并按无损原生路径单元排序。只有组件以 字面量点开头时,通配符才会选择点文件;** 不递归。非法字符类或无匹配模式会在 启动命令前失败,重定向仍必须恰好得到一个路径。每条命令及其重定向共享 32,768 个 活动模式单元、65,536 个已检查目录项与 4,096 个匹配结果的上限。被短路的条件分支 不会读取目录。

    原生程序通过持久 PATH 或显式 native: 前缀解析。ash 会把解析后的参数向量、当前 目录和导出环境直接交给解析出的宿主可执行文件,绝不插入宿主 Shell 命令字符串。 未重定向的独立子进程仍使用空 stdin 并同步捕获输出,因此自身需要前台终端的程序属于 H4 作业 控制,而不是当前行编辑 REPL。stdout 与 stderr 共享剩余的 128 MiB 捕获额度,普通 的非零原生退出状态会直接成为命令状态,不额外生成诊断。

    在 Windows 上,linux:COMMAND 会显式选择 WSL。ash 首先解析 wsl.exe;launcher 缺失时返回状态 126 与解析诊断,普通命令解析失败也绝不会隐式转入 WSL。wrapper 会收到 可选发行版、通过 --cd 传入的当前 Windows cwd,以及 --exec 后彼此独立的 Linux 命令和每个参数;不会插入宿主或 Linux Shell 字符串。当前 CLI 使用用户的默认发行版, 嵌入方可以通过 ShellOptions 显式选择;命令状态会保留 WSL backend 与所选发行版。

    原生、WSL 与可移植命令以及已实现的状态 builtin 支持 <>>>2>2>>2>&11>&2,并从左到右应用: command >out 2>&1 会把两路流合入 out,而 command 2>&1 >out 会让 stderr 保留在 原 stdout 捕获上。每个文件目标(包括 $(...) 与路径名模式)最终必须恰好得到一个 原生字段;相对 路径以持久 cwd 为基准。 文件直接连接子进程或父任务 OS 句柄,因此重定向输出不占同步捕获额度;一份经过 校验的图级顺序会按阶段与重定向源码顺序交错打开原生、可移植和状态任务文件,被后续赋值覆盖的 目标仍会打开。目标缺失、歧义或无法打开时返回状态 1 和重定向诊断。带源码位置的 Shell 诊断仍写入 Shell stderr,而不是命令原始 stderr。状态与可移植修改命令的参数、 目标都会在打开文件前完成预检;简单状态命令先打开文件再修改父状态,打开失败会阻止 状态修改、可移植文件事务或 exit 请求。WSL 重定向文件由 Windows 宿主按同一顺序打开,并直接连接 wrapper 标准句柄。

    同一行的 | 可组成两个到 32 个阶段的管道。每个阶段可以是宿主原生命令,也可以是 Windows 上显式选择的 WSL 命令、可移植 pwdecholscatgrep,也可以是 可移植 cpmvrmtouch,也可以是已实现的状态 cdexportunsetsetexit;别名、函数与尚未实现的状态命令 会在完整预检时拒绝。相邻原生或 WSL wrapper 阶段仍由 OS 管道直连。涉及进程内阶段的边界只保留显式声明的父进程 异步端点,并将有界任务与原生执行、捕获并发轮询,因此无需完整物化 原生流或可移植 cat/grep 流,且保留 OS 背压。只有 cat -grep PATTERN - 消费上游 stdin;其他可移植形式 会关闭该 reader,使上游 producer 能观察 broken-pipe 失败。最终进程内输出、最终原生 输出与捕获的原生 stderr 共享剩余的 128 MiB 额度。状态默认取最后阶段;启用 set -o pipefail 后改取最右侧失败的原生、WSL、可移植或状态阶段(含 128 + signal), 全成功时仍取最后阶段。 状态阶段不消费 stdin,在独立的 ShellState 克隆上执行,并在完成时关闭空 stdout。 父 Shell 的 cwd、变量、环境、选项与退出请求都不会改变;下游 reader 收到 EOF,管道 中的 exit 也只贡献普通阶段状态。 修改阶段同样关闭 stdin、不输出 stdout,并把事务冲突或文件系统状态交给最终阶段/ pipefail 选择;其重定向文件会按图级顺序先于事务打开。 任意原生、WSL、可移植或已实现状态阶段都可以重定向 stdin、stdout 或 stderr,描述符复制仍按源码顺序应用。若 producer 不再引用内部管道,ash 会关闭父进程 writer,使下游 reader 收到 EOF;若 consumer 用文件替换管道 stdin,ash 会关闭父进程 reader,使上游 writer 遇到原生 broken-pipe 行为,随后仍由最终阶段或 pipefail 策略决定可见状态。即使原描述符随后 被重定向,只要复制出的描述符仍引用管道,该连接就会保留。状态文件会加入同一全局 打开顺序;这些 builtin 不产生命令原始输出,重定向其空 stdout 会正常关闭下游。 WSL 阶段复用同一份经过校验的管道与文件图,不增加 relay 缓冲。 父进程管道与文件句柄领取完毕后,ash 会把原生图转换成统一作业监督器。原生退出结果 保持规格顺序;任一准备、捕获或等待失败都会在管道返回前终止并回收所有原生成员拥有 的进程树。可移植/状态 future 与捕获 drain 完成后,监督器才进入不会被中途取消的有序 等待;两阶段共用同一完成边界。

    &&|| 以相同优先级连接完整管道,并从左到右求值。&& 只在上一可见状态为 0 时执行下一管道,|| 只在其非零时执行;输入状态已经过最终阶段或 pipefail 选择。被短路的分支会为下一链接与 $? 保留该状态,不输出诊断,也不进行参数展开、 命令解析、参数预检、重定向打开、进程启动、状态修改或可移植文件事务。只有实际执行的 exit 才会停止源码。整份提交源码仍在任何副作用前完整解析,因此被跳过分支中的语法 错误也会阻止全部前缀命令。操作符后可用空白、注释与换行在同一源码中续写;未连接的 换行或 ; 会开始新的无条件列表。

    剩余命令语言(包括别名、函数与 subshell 状态)、 终端流式输出、前台交互程序与作业控制,以及 WSL 已安装发行版探测、backend 策略/配置、通用参数路径映射、环境转发、 Linux 侧所有权与中断归一化尚未实现。 常规二进制启用 human-shell feature; cargo build -p a3s-ash --no-default-features 保留最小机器专用构建。

    错误契约

    示例:

    s:1
    e{c}:
    4

    对机器命令而言,退出码按错误类别稳定映射。调用方应根据 ASON 诊断字段和退出码分支, 不应匹配本地化文本;无参数或未知机器命令返回 Usage 类错误,而不是打印帮助。 ash shell 则有意输出人类诊断和常规命令状态。

    运行目录

    文件操作受启动时工作区约束。路径必须使用规范逻辑形式,拒绝词法逃逸、符号链接或 Windows reparse point 绕过。exec 也不会自动切换到隐式系统 Shell。

    人类 Shell 状态改用原生 PathBufOsStringcdexportunsetlscatgrep 继承普通用户权限。可移植 cpmvrmtouch 则有意把当前 cwd 绑定为带日志的工作区,不能向上穿越。原生外部程序继承相同的 cwd/环境状态和普通 OS 权限。原生路径和环境单元会被保留或可逆转义;这不会削弱或替代 ASH/1 的工作区约束。