跳转至

后台 exec 和进程工具

OpenClaw 通过 exec 工具运行 shell 命令,并在内存中保留长时间运行的任务。process 工具管理这些后台会话。

exec 工具

参数:

参数 说明
command 必填。要运行的 shell 命令。
workdir 工作目录;省略则使用默认 cwd。
env 命令的额外环境变量。
yieldMs 转入后台前等待的毫秒数(默认 10000)。
background 立即在后台运行。
timeoutSeconds 超时秒数(默认 tools.exec.timeoutSeconds);到期时终止进程。设置 timeoutSeconds: 0 可禁用该次调用的 exec 进程超时。
pty 在可用时于伪终端中运行(需要 TTY 的 CLI、编码代理)。
elevated 如果启用/允许 elevated 模式,则在沙箱外运行(默认为 gateway,当 exec 目标为 node 时为 node)。
host exec 目标:auto、sandbox、gateway 或 node。
node 节点 id/名称,与 host: "node" 一起使用。

行为:

  • 前台运行会直接返回保留的输出,并披露较早输出超过聚合上限的情况。
  • 当转入后台(显式或通过 yieldMs 超时)时,工具返回 status: "running" + sessionId 和一段简短的输出尾部。
  • 启动失败会返回操作系统错误,并释放 worker 清理,即使没有进程启动。
  • 后台运行和 yieldMs 运行会继承 tools.exec.timeoutSeconds,除非调用传递了显式 timeoutSeconds。
  • 启用 秘密出口代理 时,每个由 Gateway 托管的命令会在各轮次中保留其自身的代理访问。进程退出、取消、超时或 Gateway 关闭会撤销该访问并关闭其连接。使用 process kill 可同时停止后台命令及其代理访问。
  • 返回后台会话 ID 不会停止进程超时。对于 gateway 或沙箱中的持久服务,使用 background: true 和 timeoutSeconds: 0,完成后使用 process 操作 kill 停止它。主机和 worker 生命周期限制仍然适用。
  • 输出会保留在内存中,直到会话被轮询或清除,且不超过每会话聚合上限。
  • 已完成的会话在其配置的 TTL 后过期,从完成时开始计算。每个 exec 在被接受时捕获其代理的保留设置;使用其他代理的 process 工具不会更改现有结果的寿命。注册表还最多保留 50 个已完成会话和 2,000,000 个总保留输出字符,先逐出最旧的记录。最新的已完成会话即使该记录单独超过全局限制,也保留其有上限的每会话聚合。
  • 如果 process 工具被禁止,exec 同步运行并忽略 yieldMs/background。
  • 派生的 exec 命令会收到 OPENCLAW_SHELL=exec,用于上下文感知的 shell/profile 规则。
  • 对于现在开始长时间运行的工作:启动一次,并在命令发出输出或失败后依赖自动完成唤醒(如果启用)。
  • 失败的后台命令会唤醒其源会话,即使其他会话或自动化正忙。如果该会话仍在运行,完成会等待其空闲。当监视器在其监视的工作完成前退出时,也适用此情况。
  • 手动取消的命令不会触发完成通知,即使它们产生了输出。保留的输出仍可通过 process poll 或 process log 获取。清理失败仍会通知。
  • 如果自动完成唤醒不可用,或者你需要对干净退出且无输出的命令进行静默成功确认,请使用 process 轮询。
  • 后台 exec 不会自动唤醒子代理会话。子代理必须在让出前使用 process poll 收集其命令结果,且没有其他完成源。请求停止也需要收集其终止结果。
  • 不要用 sleep 循环或重复轮询来模拟提醒或延迟后续操作——对未来工作使用 cron。

环境变量覆盖

变量 效果
OPENCLAW_BASH_YIELD_MS 转入后台前的默认 yield(毫秒)。默认 10000,限制在 10-120000。
OPENCLAW_BASH_MAX_OUTPUT_CHARS 内存中聚合上限(字符数)。默认 200000,限制在 1000-200000。
变量 效果
OPENCLAW_BASH_PENDING_MAX_OUTPUT_CHARS 每个流待处理的 stdout/stderr 上限。默认 30000,限制在 1000-200000 范围内,并受总上限约束。
OPENCLAW_BASH_JOB_TTL_MS 已结束会话的 TTL(毫秒),限制在 1m-3h 范围内。
OPENCLAW_PROCESS_INPUT_WAIT_IDLE_MS 在可写入的后台会话被标记为可能正在等待输入之前的空闲输出阈值。默认 15000。

配置(优先于环境变量覆盖)

键 默认值 效果
tools.exec.backgroundMs 10000 与 OPENCLAW_BASH_YIELD_MS 相同。
tools.exec.timeoutSeconds 1800 每次调用的默认超时。
tools.exec.cleanupMs 1800000 与 OPENCLAW_BASH_JOB_TTL_MS 相同。
tools.exec.notifyOnExit true 当后台 exec 退出时,入队一个系统事件并请求心跳。
tools.exec.notifyOnExitEmptySuccess false 对于成功且无输出的后台运行,也入队完成事件。

禁用自动完成轮次

后台 exec 完成通知默认启用。即使 agents.defaults.heartbeat.every 为 "0m",它们也可以运行标记为 [OpenClaw exec completion] 的模型轮次:该设置禁用的是周期性轮询,而不是完成后续处理。

要让后台命令继续运行而不触发自动完成轮次,请设置:

openclaw config set tools.exec.notifyOnExit false

某个 agent 的 agents.entries.<id>.tools.exec.notifyOnExit 会覆盖全局设置。也请将该项覆盖设置为 false,或移除它以继承全局值。新启动的命令使用更新后的设置;已在运行的命令保留其启动时的设置。使用 process poll 或 process log 按需收集其结果。这会禁用完成事件及其自动模型调用,而不会禁用 background: true 或 process 工具。

工作进程环境

在配对节点或基于节点的云工作进程中,后台进程属于会话的环境。结束或取消一个轮次时,已转入后台的命令会继续运行。同一环境中的后续轮次可以使用 process 来轮询、发送输入或停止它们;前台命令仍会在其轮次被取消时停止。

保留的工作进程占用一个节点工作进程槽位。复用它不需要额外槽位。如果命令在轮次之间结束,其保留的输出仍可供下一个轮次使用,但受常规进程输出限制和 TTL 约束。一旦某个轮次结束时没有存活的后台命令,工作进程就会退出。迁移或退役环境、替换其所有权或停止节点,也会停止其进程。进程句柄无法在节点或工作进程重启后保留。

如果节点的配对被撤销,或其提供商不再识别该租约,则会话放置会失败。物理清理可能会保持待定状态,直到 OpenClaw 确认确切的工作进程已停止;未确认的停止不会释放其所有权记录。

工作进程完成目前不会自动唤醒 Gateway 会话;请在后续轮次中使用 process poll 检查结果。关闭 portal 会关闭其代理,而不是开发服务器:使用 process kill 停止服务器。

子进程桥接

主机 exec 命令结束后,OpenClaw 会在报告完成之前释放其保留的进程作用域。由 shell 后台化(&)遗留的子进程会随该作用域一起停止。要在多个轮次之间继续工作,请使用 background: true 启动长时间运行的命令,并使用 process 收集其结果。其作用域保持归属,直到命令结束;沙箱运行时生命周期仍由沙箱后端保留。

在 exec/process 工具之外生成长时间运行的子进程时(CLI 重新生成、gateway 辅助程序),请附加子进程桥接辅助程序,以便终止信号能够转发,并在退出/关闭时分离监听器。这可以避免在 systemd 上产生孤儿进程,并保持跨平台关闭行为一致。

在 Linux 上使用默认 Node 运行时,Gateway 会在加载其主运行时之前启动一个小型派生代理。 如果初始派生代理启动失败,Gateway 会记录失败原因和运行时入口路径,然后在该 Gateway 进程的其余部分使用进程内派生。 新的 Gateway 进程会再次尝试派生代理。 当派生代理就绪后,exec 命令、shell 快照捕获与验证,以及使用共享命令运行器的辅助程序都会从它派生,因此 Linux 不会为每个命令复制 Gateway 的页表。现有的进程监督程序和服务中继仍负责取消、输出和清理。在派生代理首次就绪后,派生代理丢失会使受影响的命令失败,而不是重新运行它们;后续命令会使用重启后的派生代理。一次性 CLI 命令、原生文件描述符输入以及独立启动的应用程序会保留其本地进程传输方式,Bun、macOS 和 Windows 也是如此。 派生代理拥有自己的进程组,Gateway 会在派生代理丢失时终止该进程组;服务中继也保留其自身的父进程丢失清理。 一个分离的子进程可能在派生代理崩溃后、其 PID 被报告之前仍然存活,这与 Gateway 崩溃时直接派生的子进程现有的残留行为一致。

规范凭据读取器也使用代理。如果它确认某个读取器从未启动,读取会回退一次到本地进程,并使用原始环境和工作目录。取消、超时、不确定的启动和清理失败不会触发重试。基于快照的凭据读取器保留其本地进程传输。

受监督命令的超时还涵盖启动阶段,包括被阻塞的私有输入投递。超时结果可能在清理仍在继续时返回。作用域退役和 Gateway 关闭会分别等待清理所有者;当该所有者报告不确定时,它们会报告失败,而不是将超时视为命令已停止的证明。

在 Linux 上使用 Node 的托管 exec 和协商的工作区命令使用专用的子进程 subreaper。它在启动前获取内核子进程所有权,接管孤立的子孙进程,并停止和回收它们,即使它们创建了另一个进程组或会话。完成需要内核报告没有剩余子进程、匹配的所有者回执以及输出排空。它不单独依赖面向进程组的信号、进程表普查或继承管道关闭。

可移植工作器使用其已准入 Node 主机提供的原生辅助程序;可移植归档不会获取原生依赖。在禁止进程组信号的环境中,使用匹配的当前主机和工作器构建。不受支持的所有权契约会在启动前失败,而不是降级为仅传输清理。源码安装必须构建其进程辅助程序;具有独立子进程回收器的源码加载器不能共享此所有权。

node 日志将 Linux 子孙进程灭绝与旧的血缘回执分开记录。存活的宿主所有者可以在其主机停止后发布该事实。重启后,缺失的证书或不确定的所有者身份会保留物理预留;重启并不是旧子孙进程已停止的证明。旧构建不会将新证书重新解释为血缘完成。

macOS 和保留的 Bun 进程组所有者仍需要内核进程组消失。权限拒绝探测永远不能证明不存在。仅命令完成或输出管道关闭并不能确立其子孙进程已停止。本地 TUI shell 关闭对其自身命令使用相同的清理所有者。如果主机繁忙,清理进程会在报告超时之前排队原生完成事件。

一次性工具清理会保持已配置沙箱运行时处于其会话、代理或共享生命周期。它加入该命令的本地命令传输和后端清理。它不会停止共享沙箱,也不会声称所有远程子孙进程都已退出。主机命令,包括来自沙箱会话的提升命令,仍需要拥有的进程树清理。

当主机命令需要进程树清理时,pty 请求会在启动原生 PTY 之前回退到子进程路径并报告警告。需要终端的命令在该回退下可能失败。清理失败保持不确定状态,而不是被报告为干净关闭。

process 工具

操作:

操作 效果
list 运行中 + 已完成的会话。
poll 排空会话的新输出(同时报告退出状态)。
log 读取聚合输出和输入恢复提示。支持 offset + limit。
write 发送 stdin(data,可选 eof)。
send-keys 向基于 PTY 的会话发送显式按键令牌或字节。
submit 向基于 PTY 的会话发送回车/换行。
paste 发送字面文本,可选地包裹在括号粘贴模式中。
kill 终止后台会话。
clear 从内存中移除已完成的会话。
remove 如果正在运行则终止,否则如果已完成则清除。

说明:

  • 仅后台会话会被列出/持久化——仅保存在内存中,不在磁盘上。进程重启后会话会丢失。
  • 重置或删除会话只会清除其已完成的后台进程;其他会话、显式共享作用域和正在运行的进程不受影响。
  • 存活的后台会话会阻止协作式主机挂起和安全的 Gateway 重启,直到进程所有者确认其实际退出。
  • process remove 可以在请求终止后立即隐藏正在运行的会话;挂起和重启在退出确认之前仍保持阻止。
  • 只有当你运行 process poll/log 且工具结果被记录时,会话日志才会保存到聊天历史。
  • process 按代理作用域划分;它只能看到由该代理启动的会话。
  • 在显式 kill 或任务取消后,poll 和 log 会将已确认的请求停止报告为完成的观察,并保留进程的信号和取消原因。意外终止、超时和清理失败仍为错误。进程列表保留底层终端状态。
  • 当自动完成唤醒不可用时,使用 poll/log 获取状态、日志或完成确认。
  • 在恢复交互式 CLI 之前使用 log,以便当前转录、stdin 状态和输入等待提示一起可见。
  • 当需要输入或干预时,使用 write/send-keys/submit/paste/kill。
  • process list 包含派生的 name(命令动词 + 目标),便于快速扫描。
  • process list、poll 和 log 仅在会话仍有可写 stdin 且空闲时间超过输入等待阈值(默认 15000 ms,OPENCLAW_PROCESS_INPUT_WAIT_IDLE_MS)时报告 waitingForInput。
  • process log 使用基于行的 offset/limit。当两者都省略时,它返回最后 200 行并附带分页提示。当设置了 offset 而未设置 limit 时,它从 offset 返回到末尾(不限制为 200)。
  • process poll 和 process log 区分在聚合保留上限处被丢弃的输出与仅由待处理缓冲区或保留尾部省略的输出。被丢弃的输出无法恢复;分页日志只能检查保留的部分。
  • poll 的 timeout 最多等待相应毫秒数后返回;超过 30000 的值会被限制为 30000。
  • 轮询用于按需状态,而不是等待循环调度。如果工作应稍后发生,请使用 cron。

在 Code Mode 中,process 会直接返回其结构化详细信息。 对于 action: "log",output 包含所请求的日志页面,包括分页、 保留策略和输入恢复提示。失败的 process 操作会包含 error 消息,并伴随 status: "failed",以便智能体选择下一个操作。

示例

运行一个超过默认 10000 ms yield 窗口的任务,稍后再轮询:

{ "tool": "exec", "command": "sleep 30 && echo done" }
{ "tool": "process", "action": "poll", "sessionId": "<id>" }

在发送输入之前检查交互式会话:

{ "tool": "process", "action": "log", "sessionId": "<id>" }

立即在后台启动:

{ "tool": "exec", "command": "npm run build", "background": true }

发送 stdin:

{ "tool": "process", "action": "write", "sessionId": "<id>", "data": "y\n" }

发送 PTY 按键:

{ "tool": "process", "action": "send-keys", "sessionId": "<id>", "keys": ["C-c"] }

提交当前行:

{ "tool": "process", "action": "submit", "sessionId": "<id>" }

粘贴字面文本:

{ "tool": "process", "action": "paste", "sessionId": "<id>", "text": "line1\nline2\n" }

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw