15.1 Bash 执行引擎
生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~120k tokens,输出 ~6k tokens(本节)
上一章我们全面了解了 OpenClaw 的工具系统——工具如何注册、如何执行、如何控制权限。从本章开始,我们将深入到具体工具实现层面。Bash 执行引擎是 OpenClaw 中最复杂、安全要求最高的工具:它让 AI Agent 具备了在操作系统上执行任意命令的能力,但同时也带来了巨大的安全风险。本节将从命令执行核心出发,逐步解析 PTY 终端模拟、PATH 管理以及安全审批等关键机制。
15.1.1 exec 工具的总体架构
源文件分布
Bash 工具的实现分布在多个文件中:
bash-tools.ts
桶文件(barrel),re-export exec 和 process 工具
bash-tools.exec.ts
exec 工具核心——命令执行引擎(~1630 行)
bash-tools.process.ts
process 工具——后台进程管理
bash-tools.shared.ts
共享工具函数(环境变量、工作目录、日志截取)
bash-process-registry.ts
进程注册表——内存中管理所有 exec 会话
shell-utils.ts
Shell 配置检测、二进制输出清理、进程树杀死
pty-dsr.ts
PTY DSR(Device Status Report)请求处理
pty-keys.ts
PTY 按键编码(send-keys、paste 操作)
exec-approvals.ts(infra/)
命令审批系统——白名单、安全策略评估
三种执行宿主模式
exec 工具支持三种执行宿主(Host),对应不同的安全级别:
衍生解释:在容器化(Containerization)技术中,Docker 是最流行的容器引擎。"sandbox" 模式下,OpenClaw 在一个 Docker 容器内执行命令,容器与宿主机文件系统和网络隔离,即使 AI 执行了恶意命令,也不会影响宿主系统。这是经典的**沙箱(Sandbox)**安全模型。
工具 Schema 定义
exec 工具通过 TypeBox 定义参数 Schema,LLM 可以理解并填入:
注意 yieldMs 和 background 参数:这是 OpenClaw 的特色设计。命令执行可以先同步等待一段时间(默认 10 秒),如果命令尚未完成,就自动转入后台——这比简单的"同步阻塞到完成"或"立即后台化"更灵活。
15.1.2 命令执行核心流程
createExecTool() 工厂函数
createExecTool() 工厂函数exec 工具由工厂函数 createExecTool(defaults?) 创建。工厂接收默认配置参数(ExecToolDefaults),返回一个 AgentTool 实例。核心配置项包括:
execute 处理链
当 LLM 调用 exec 工具时,execute 函数依次执行以下步骤:
15.1.3 三种进程创建方式
runExecProcess() 根据配置选择不同的进程创建策略:
策略一:Docker 沙箱执行
关键点:
buildDockerExecArgs()构建docker exec -i [-t] -w <dir> -e KEY=VAL ... <container> sh -lc '<command>'命令使用
-l(login shell)确保.profile等初始化脚本被加载,从而获得完整的 PATHspawnWithFallback()提供降级机制——如果detached模式 spawn 失败(某些 Node.js 版本/平台限制),自动回退到非 detached 模式
衍生解释:
detached: true是 Node.jschild_process.spawn()的选项,表示子进程与父进程分离运行。在 Unix 系统上,这会创建一个新的进程组(Process Group),使得父进程退出时子进程不会被杀死。OpenClaw 需要这个特性来支持后台长时间运行的命令。
策略二:PTY 模拟终端执行
衍生解释:PTY(Pseudo Terminal,伪终端)是操作系统内核提供的一种机制,它模拟了一个终端设备。许多命令行程序(如
vim、htop、less)会检测自己是否运行在终端中——如果不是(比如 stdout 是管道),它们会改变行为(禁用颜色、不显示 TUI 界面、甚至拒绝运行)。通过 PTY,OpenClaw 可以让这些程序认为自己运行在一个真正的终端里。
PTY 模式有几个特殊之处:
终端尺寸:设置为 120 列 × 30 行,这是典型的终端尺寸
TERM 环境变量:默认为
xterm-256color,支持 256 色输出stdin 适配:PTY 不使用 Node.js 的
child.stdin,而是通过pty.write()写入EOF 信号:Unix 用
\x04(Ctrl-D),Windows 用\x1a(Ctrl-Z)自动降级:如果
node-pty模块不可用(未安装或平台不支持),自动回退到普通 spawn
策略三:普通子进程执行
最简单的模式:获取系统 Shell(通过 getShellConfig()),然后用 -c 参数执行命令。
15.1.4 PTY 数据流处理
PTY 模式下,数据流的处理与普通 child_process 有显著差异。
DSR 请求过滤
衍生解释:DSR(Device Status Report)是终端控制序列标准(ANSI/VT100)的一部分。当程序向终端发送
ESC[6n时,它期望终端回复当前光标位置(格式为ESC[行;列R)。像vim、zsh等程序在启动时会发送 DSR 来获取光标位置。OpenClaw 的 PTY 层需要"假装"自己是终端来回复这些查询,否则程序会一直等待回复而卡住。
DSR 处理的实现非常精练,只有 16 行:
输出格式对比
stdout/stderr 分离
✓ 独立流
✗ 混合在一起
ANSI 颜色码
通常无
包含
DSR 查询
无
需要过滤和回复
TUI 程序支持
不支持
支持
数据事件
child.stdout.on('data')
pty.onData()
15.1.5 环境变量安全机制
宿主模式环境变量黑名单
当执行宿主为 gateway(宿主机)或 node(远程节点)时,OpenClaw 会严格检查 Agent 请求的环境变量:
衍生解释:
LD_PRELOAD攻击是 Linux 系统上一种经典的代码注入技术。LD_PRELOAD环境变量指定一个共享库(.so 文件),这个库会在所有其他库之前被加载。攻击者可以用自定义库覆盖标准库函数(如read()、write()),从而拦截或篡改程序行为。类似地,macOS 上的DYLD_INSERT_LIBRARIES具有相同的危害。
验证函数会拒绝任何尝试设置这些变量的请求:
注意:sandbox(Docker)模式跳过此检查——因为容器内的环境变量不会影响宿主机。
PATH 管理策略
不同模式下的 PATH 处理各不相同:
Safe Bins(安全二进制白名单)
在 allowlist 安全模式下,如果命令是这些"安全"工具之一(且不带文件路径参数),可以直接执行而不需要审批。isSafeBinUsage() 函数做了精细的检查:
命令的可执行文件名必须在
safeBins集合中可执行文件必须解析到具体路径(防止 PATH 注入)
参数中不能包含文件路径(防止读写敏感文件)
15.1.6 命令审批系统
审批文件结构
命令审批的配置存储在 ~/.openclaw/exec-approvals.json:
三层安全策略
最严格
deny
—
拒绝一切执行
白名单
allowlist
on-miss
匹配白名单则执行,否则询问用户
全开放
full
off
直接执行(仅适用于沙箱)
minSecurity() 函数确保安全等级只能降低(取最小值):
Shell 命令分析引擎
在评估白名单时,OpenClaw 需要解析 Shell 命令来提取可执行文件路径。这是一个迷你的 Shell 解析器:
命令解析器支持:
链式操作符:
&&、||、;管道:
|单引号和双引号
转义字符
\拒绝的危险 token:
>、<、`、$()、\n
审批流程
当命令不在白名单中且 ask 不为 off 时,触发用户审批:
审批请求通过 Unix Domain Socket 传递,确保只有本机进程能参与审批。
15.1.7 后台化与产出收集
yieldMs 机制
exec 工具最巧妙的设计之一是 yieldMs——在命令执行期间,先同步等待一段时间,如果命令没完成就自动转入后台:
这个设计的好处:
快速命令(如
ls、cat)直接返回结果,无需额外的 poll 调用长时间命令(如
npm install、make)不会阻塞 Agent 的对话循环Agent 可以在等待时继续处理其他任务,然后用
process工具检查结果
超时处理
超时后的处理分两步:
立即杀死进程(通过
killProcessTree()杀掉整个进程树)等待 1 秒让内核清理,然后标记会话为
failed并收集已有输出
本节小结
exec 工具是 OpenClaw 最复杂的工具,约 1630 行代码,涉及进程管理、安全审批、PTY 终端等多个子系统
三种执行宿主:sandbox(Docker 隔离)、gateway(宿主机直接执行)、node(远程节点 RPC)
三种进程创建方式:Docker exec、PTY spawn(node-pty)、普通 child_process spawn,每种都有降级策略
PTY 模式需要处理 DSR 请求——伪装为终端回复光标位置查询,否则 TUI 程序会卡住
多层安全防护:环境变量黑名单、PATH 修改禁止、白名单 + safe bins、用户审批流程
Shell 命令解析器支持链式操作、管道、引号,可以精确提取每个管道段的可执行文件路径
yieldMs 设计让快速命令直接返回、长时间命令自动后台化,兼顾响应速度和非阻塞性
Last updated