- 人工智能
- 大模型
- LLM 网关
- AI Agent
- 即时通讯
【免费下载链接】openclaw-zero-token
OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi
本文基于 OpenClaw 官方文档 exec.md 与仓库源码,系统讲解 exec 工具的完整用法:前台/后台执行模型与yieldMs/background语义、host/security/ask三级执行路由、PATH 与环境变量安全策略、/exec会话级覆盖、exec 审批流程、allowlist 与 safe bins 机制,以及实验性apply_patch子工具。读完后你将能够在 OpenClaw 中安全地驱动任意 shell 命令、管理后台进程会话,并配置符合最小信任原则的执行策略。
exec 是什么:前台 + 后台双模执行
exec 是 OpenClaw Agent 在 workspace 中运行 shell 命令的核心工具,支持前台同步执行,也支持通过process工具接管后台执行:
- 如果
process工具被禁用(工具策略 deny),exec 会退化为同步执行,并忽略yieldMs/background参数(此时会附带警告 "Warning: background execution is disabled; running synchronously."); - 后台会话(background sessions)按 agent 隔离作用域:
process只能看到同一个 agent 发起的会话,跨 agent 不可见。
从源码看,会话隔离由 process 工具 中的scopeKey过滤实现(isInScope对每个会话的scopeKey做匹配),exec 创建时通过defaults?.scopeKey注入该键。
参数一览
exec 的参数定义在 execSchema 中,与文档逐项对应:
| 参数 | 类型 | 说明 |
|---|---|---|
command | string(必填) | 要执行的 shell 命令 |
workdir | string | 工作目录,默认取 cwd |
env | object | 环境变量 key/value 覆盖 |
yieldMs | number | 默认 10000,等待该时长后自动转后台 |
background | bool | 立即转后台 |
timeout | number(秒) | 默认 1800,超时杀死进程 |
pty | bool | 在可用时以伪终端(PTY)运行,适用于 TTY-only CLI、coding agent、终端 UI |
host | string | 执行位置:sandbox \| gateway \| node |
security | string | gateway/node的强制模式:deny \| allowlist \| full |
ask | string | gateway/node的审批提示:off \| on-miss \| always |
node | string | host=node时指定的 node id/名称 |
elevated | bool | 请求 elevated 模式(gateway host);仅当 elevated 解析为full时才强制security=full |
几个关键的默认值在源码中有精确约束:
yieldMs会被钳制到10~120000 毫秒之间(可通过环境变量PI_BASH_YIELD_MS修改默认值),见 createExecTool;background=true等价于把 yield 窗口设为 0,立即 resolve 为后台(yieldWindow 计算逻辑);timeout默认1800 秒(30 分钟),到点强制终止;- 命令输出上限:前台聚合输出默认 200,000 字符(
DEFAULT_MAX_OUTPUT,可用PI_BASH_MAX_OUTPUT_CHARS调整),后台 pending 输出默认 30,000 字符(DEFAULT_PENDING_MAX_OUTPUT),见 常量定义。
exec 的官方描述也写明了使用意图:"Execute shell commands with background continuation. Use yieldMs/background to continue later via process tool. Use pty=true for TTY-required commands (terminal UIs, coding agents)."(工具描述)。
文档列出的 10 条行为约定(Notes)
原文档的 Notes 全部值得逐条留意,这里完整继承并补充源码佐证:
host默认sandbox;elevated在 sandbox 关闭时被忽略——因为 exec 本来就在宿主上运行,无需再提升;gateway/node的审批由~/.openclaw/exec-approvals.json控制——源码中tools.exec.ask未显式设置时会回落到该文件的defaults.ask(ask 解析);node需要已配对的 node(companion app 或 headless node host);- 多个 node 可用时,通过
exec.node参数或tools.exec.node配置选择其一; - 非 Windows 宿主上使用
$SHELL;若SHELL是fish,则优先从PATH找bash(或sh)以避免 fish 不兼容脚本,两者都不存在才回退到SHELL。这一逻辑与 getShellConfig 完全一致; - Windows 宿主优先探测 PowerShell 7(
pwsh):依次检查 Program Files、ProgramW6432,再到 PATH,最后回退到 Windows PowerShell 5.1(resolvePowerShellPath)。之所以不用 cmd.exe,是因为许多 Windows 系统工具通过 WriteConsole API 直接写控制台、绕过 stdout 管道,而 PowerShell 能正确捕获重定向输出(见 Windows 分支注释); - 宿主执行(
gateway/node)拒绝env.PATH和 loader 覆盖(LD_*/DYLD_*),防止二进制劫持或注入代码; - OpenClaw 会在派生命令环境中设置
OPENCLAW_SHELL=exec(包括 PTY 与 sandbox 执行),便于 shell/profile 规则识别 exec 工具上下文。该值在 bash-tools.exec-runtime.ts 注入,并有专门测试覆盖:gateway 场景测试 和 PTY 场景测试; - 重要:sandbox 默认关闭(off by default)。若 sandbox 关闭且显式配置/请求了
host=sandbox,exec 会fail closed(直接报错失败)而不是悄悄落到 gateway 宿主上执行。此时应当启用 sandboxing,或改用带审批的host=gateway。对应实现见 sandbox 可用性检查,错误信息会明确提示启用agents.defaults.sandbox.mode="non-main"或"all"。
此外还有一条容易遗漏:脚本预检(preflight)只检查有效workdir边界内的文件。若脚本路径解析到workdir之外,则该文件跳过预检。
host 路由:sandbox / gateway / node 的决策与限制
exec 的host参数决定命令在哪里执行。源码中的决策链(createExecTool)比文档描述更严格:
- 请求的
host必须与配置值tools.exec.host完全一致,否则直接抛错:exec host not allowed (requested ...; configure tools.exec.host=... to allow).; - 唯一例外是
elevated=true:此时host被强制改写为gateway; security取配置值与请求值的交集方向最严格值(minSecurity),ask取更严格值(maxAsk)——即单次调用只能收紧、不能放松审批;- elevated 解析为
full模式时,security直接置为full且ask置为off(绕过审批)。
security的默认值随 host 变化:sandbox 默认deny,gateway/node 未设置时默认allowlist(security 解析)。
PATH 处理与环境变量安全
PATH 是 exec 安全模型中最重要的变量。原文档的 PATH handling 小节按 host 分为三种情况,完整继承如下:
host=gateway:会把登录 shell 的PATH合并进 exec 环境;env.PATH覆盖在宿主执行中被拒绝。daemon 自身仍运行在极简PATH下:- macOS:
/opt/homebrew/bin、/usr/local/bin、/usr/bin、/bin - Linux:
/usr/local/bin、/usr/bin、/bin
源码中对应 login-shell PATH 获取与合并(
getShellPathFromLoginShell+applyShellPath)。- macOS:
host=sandbox:容器内以sh -lc(login shell)运行,因此/etc/profile可能重置PATH。OpenClaw 在 profile source 之后通过内部环境变量前置env.PATH(无 shell 插值,避免注入),tools.exec.pathPrepend在此同样生效;host=node:只把未被屏蔽的 env 覆盖发送到 node。env.PATH覆盖在宿主执行中被拒绝、在 node host 上被忽略。若 node 需要额外 PATH 条目,应配置 node host 服务的运行环境(systemd/launchd)或把工具安装到标准位置。
宿主执行的环境变量净化集中在 sanitizeHostExecEnvWithDiagnostics:blockPathOverrides: true时,任何env.PATH覆盖都会抛出Security Violation: Custom 'PATH' variable is forbidden during host execution.;单个其他危险键(LD_*/DYLD_*等)被拦截时抛Security Violation: Environment variable '<key>' is forbidden during host execution.;多个键被拦截时聚合报错并列出 blocked/invalid 清单。通用的净化规则与 fail-closed 校验见 sanitizeHostBaseEnv / validateHostEnv。
tools.exec.pathPrepend只对本地(gateway)与 sandbox 有意义:当host=node时该配置被忽略并附加警告 "tools.exec.pathPrepend is ignored for host=node. Configure PATH on the node host/service instead."(pathPrepend 分支)。
每 agent 绑定 node(配置方式)
使用 agent 列表下标(配置中的索引):
openclaw config get agents.list openclaw config set agents.list[0].tools.exec.node "node-id-or-name"Control UI 中,Nodes 标签页提供了一个小的 "Exec node binding" 面板,可配置同样的设置。
配置项全解(tools.exec.*)
原文档 Config 小节的全部配置项如下(默认值已与源码核对):
| 配置键 | 默认值 | 说明 |
|---|---|---|
tools.exec.notifyOnExit | true | 为 true 时,后台 exec 会话退出后入队一个 system event 并请求 heartbeat(源码:defaults?.notifyOnExit !== false,见 notifyOnExit 解析) |
tools.exec.approvalRunningNoticeMs | 10000 | 审批门控的 exec 运行超过该毫秒数时发出一次"running" 通知;0表示禁用(resolveApprovalRunningNoticeMs,默认常量 10_000) |
tools.exec.host | sandbox | 默认执行位置 |
tools.exec.security | sandbox 为deny;gateway + node 未设置时为allowlist | 执行安全模式 |
tools.exec.ask | on-miss | 审批提示模式 |
tools.exec.node | 未设置 | 默认目标 node |
tools.exec.pathPrepend | — | exec 运行时前置到PATH的目录列表(仅 gateway + sandbox) |
tools.exec.safeBins | — | 仅 stdin 的安全二进制,可运行于无显式 allowlist 条目;行为细节见 Safe bins(stdin-only) |
tools.exec.safeBinTrustedDirs | — | safeBins路径检查额外信任的显式目录。PATH条目永不被自动信任;内建默认为/bin和/usr/bin |
tools.exec.safeBinProfiles | — | 每个 safe bin 的可选自定义 argv 策略(minPositional、maxPositional、allowedValueFlags、deniedFlags) |
pathPrepend的文档示例:
{ tools: { exec: { pathPrepend: ["~/bin", "/opt/oss/bin"], }, }, }退出通知的实际行为(maybeNotifyOnExit):仅对已后台化且未通知过的会话生效,汇总文本形如Exec completed (abcd1234, code 0) :: <输出尾部 400 字符>,然后入队 system event 并请求一次 scoped heartbeat(reason 为exec:<session-id>:exit)。默认成功但输出为空时不通知(除非显式开启notifyOnExitEmptySuccess)。
会话级覆盖:/exec指令
用/exec可为当前会话设置host、security、ask、node的会话级默认值;不带参数发送/exec可查看当前值。
/exec host=gateway security=allowlist ask=on-miss node=mac-1该指令的解析实现在 parseExecDirectiveArgs:按key=value或key:valuetoken 切分,host只接受sandbox|gateway|node、security只接受deny|allowlist|full、ask只接受off|on-miss|always,非法取值会被标记为 invalid 而不生效。
授权模型
/exec只对授权发送者生效(渠道 allowlist/pairing 加上commands.useAccessGroups)。它只更新会话状态,不写配置。要硬性禁用 exec,应通过工具策略拒绝(tools.deny: ["exec"]或按 agent 配置)。除非你显式设置security=full且ask=off,否则宿主审批依然适用。
Exec 审批(companion app / node host)
沙箱化的 agent 可以在exec落到 gateway 或 node 宿主执行前要求逐次审批。策略、allowlist 与 UI 流程的完整细节见 Exec approvals。
审批流程的关键行为(均有源码对应):
- 需要审批时,exec 工具立即返回
status: "approval-pending"和一个 approval id; - 提示消息由 buildApprovalPendingMessage 生成,包含短代码(8 位 slug)、完整 id、host/node、CWD、命令代码块,并给出回复格式:
Reply with: /approve <slug> allow-once|allow-always|deny;背景模式要求预授权策略(allow-always 或ask=off); - 审批超时默认 120 秒(
DEFAULT_APPROVAL_TIMEOUT_MS = 120_000,请求超时 130 秒,见 常量); - 审批通过(或拒绝/超时)后,Gateway 发出 system event(
Exec finished/Exec denied); - 若命令批准后仍在运行且超过
tools.exec.approvalRunningNoticeMs,只发出一次Exec running通知。
Allowlist 与 safe bins
- 手动 allowlist 只匹配解析后的二进制路径(resolved binary paths),不做 basename 匹配。
security=allowlist时,shell 命令只有在每个管道段都在 allowlist 中或属于 safe bin 时才被自动放行; - 链式命令(
;、&&、||)在 allowlist 模式下被拒绝,除非每个顶层段都满足 allowlist(含 safe bin);重定向(redirection)始终不支持; autoAllowSkills是 exec approvals 中一条独立的便捷路径,不等于手动 allowlist 条目。若追求严格显式信任,保持autoAllowSkills关闭;- 四个控制项各司其职:
tools.exec.safeBins:小的、仅 stdin 的流过滤器;tools.exec.safeBinTrustedDirs:safe-bin 可执行路径的显式额外信任目录;tools.exec.safeBinProfiles:自定义 safe bin 的显式 argv 策略;- allowlist:对可执行路径的显式信任。
不要把safeBins当作通用 allowlist,也不要加入解释器/运行时二进制(如python3、node、ruby、bash)——需要这些时请使用显式 allowlist 条目并保持审批提示开启。源码中对此有启动期检查:未配置 profile 的 safeBins 条目会被忽略并打日志,解释器类条目会被单独警告 "interpreter/runtime binaries in safeBins (...) are unsafe without explicit hardened profiles"(safe bin 策略解析,策略实现见 resolveExecSafeBinRuntimePolicy)。
此外,openclaw security audit会在解释器/运行时safeBins条目缺少显式 profile 时给出警告,openclaw doctor --fix可以为缺失的自定义safeBinProfiles条目生成脚手架。完整策略与示例见 Safe bins versus allowlist。
实战示例
前台执行
{ "tool": "exec", "command": "ls -la" }后台 + 轮询
{"tool":"exec","command":"npm run build","yieldMs":1000} {"tool":"process","action":"poll","sessionId":"<id>"}命令在yieldMs到期后自动转后台,exec 返回的提示文本形如Command still running (session <id>, pid <pid>). Use process (list/poll/log/write/kill/clear/remove) for follow-up.(resolveRunning)。poll的timeout参数表示最多等待的毫秒数,上限 120,000 ms(MAX_POLL_WAIT_MS)。
process 工具支持的完整动作集为:list、poll、log、write、send-keys、submit、paste、kill、clear、remove(processSchema),log默认返回最后 200 行,可用offset/limit分页。
发送按键(tmux 风格)
{"tool":"process","action":"send-keys","sessionId":"<id>","keys":["Enter"]} {"tool":"process","action":"send-keys","sessionId":"<id>","keys":["C-c"]} {"tool":"process","action":"send-keys","sessionId":"<id>","keys":["Up","Up","Enter"]}按键编码在 pty-keys.ts 中实现,测试见 bash-tools.process.send-keys.test.ts。
提交(只发 CR)
{ "tool": "process", "action": "submit", "sessionId": "<id>" }粘贴(默认 bracketed 模式)
{ "tool": "process", "action": "paste", "sessionId": "<id>", "text": "line1\nline2\n" }paste支持bracketed布尔参数控制是否用 bracketed paste 模式包裹。
apply_patch(实验性)
apply_patch是exec的子工具(subtool),用于结构化多文件编辑,需要显式启用:
{ tools: { exec: { applyPatch: { enabled: true, workspaceOnly: true, allowModels: ["gpt-5.2"] }, }, }, }注意事项(与文档逐条对应):
- 仅对 OpenAI / OpenAI Codex 模型可用;
- 工具策略仍然生效:
allow: ["exec"]会隐式允许apply_patch; - 配置位于
tools.exec.applyPatch; tools.exec.applyPatch.workspaceOnly默认true(限制在工作区内);只有在你有意希望apply_patch在工作区目录之外写/删文件时才设为false。
从源码看,patch 采用*** Begin Patch/*** End Patch标记格式,支持*** Add File:、*** Delete File:、*** Update File:、*** Move to:、@@变更上下文与*** End of File标记(标记定义与 hunk 结构)。workspaceOnly在 createApplyPatchTool 中默认为true(options.workspaceOnly !== false),每次应用都会逐 hunk 检查AbortSignal并返回added/modified/deleted三类操作汇总。测试覆盖见 apply-patch.test.ts。
失败语义与超时提示
补充一个文档未展开但对调试重要的细节:exec 会把退出结果分类为completed/failed,失败原因(failureKind)包括shell-command-not-found(exit 127)、shell-not-executable(exit 126)、overall-timeout、no-output-timeout、signal、aborted(classifyExecFailureKind 与 formatExecFailureReason)。超时提示会明确建议提高超时,例如 "Command timed out after 30 seconds. ... re-run with a higher timeout (e.g., exec timeout=300)."。值得注意的是:后台化请求(background/yieldMs且未显式指定timeout)会豁免整体超时(backgroundTimeoutBypass),因为长任务本应通过process轮询管理。
小结
OpenClaw 的 exec 工具围绕"默认保守、显式放宽"构建:host必须与配置一致、sandbox 未启用时 fail closed、宿主执行拒绝PATH/loader 环境变量覆盖、allowlist 只认解析后的完整路径、safe bins 限制为 stdin-only 过滤器,且审批只能收紧不能放松(minSecurity/maxAsk)。在这套约束之上,yieldMs/background+process提供了完整的前后台进程生命周期管理(poll、log、write、send-keys、submit、paste、kill),/exec提供了不污染全局配置的会话级临时覆盖。相关源码入口集中在 src/agents/bash-tools.exec.ts、src/agents/bash-tools.exec-runtime.ts、src/agents/bash-tools.process.ts、src/agents/shell-utils.ts、src/agents/apply-patch.ts,审批策略详解可继续查阅 docs/tools/exec-approvals.md。
- 人工智能
- 大模型
- LLM 网关
- AI Agent
- 即时通讯
【免费下载链接】openclaw-zero-token
OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi
相关推荐
OpenClaw exec 工具全解析:从命令执行、后台会话到审批授权与安全边界
OpenClaw exec 工具全解析:从命令执行、后台会话到审批授权与安全边界 exec 是 OpenClaw 中驱动 Agent 操作真实系统的核心工具,它
人工智能AI Agent即时通讯后端本地部署语音OpenClaw Exec Host 重构方案:sandbox / gateway / node 三级执行路由与审批体系详解
OpenClaw Exec Host 重构方案:sandbox / gateway / node 三级执行路由与审批体系详解 导读 本文基于 OpenClaw
人工智能AI Agent即时通讯后端本地部署语音OpenClaw 主机命令执行审批(Exec Approvals)完整指南:allowlist、safe bins 与跨渠道审批实战
OpenClaw 主机命令执行审批(Exec Approvals)完整指南:allowlist、safe bins 与跨渠道审批实战 导读 Exec Appro
人工智能大模型LLM 网关AI Agent即时通讯
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考