第 6 章 Shell 执行

Shell 是最强也是最危险的能力

给 agent 开放 shell,它就能做几乎任何事:跑测试、安装依赖、启动服务、部署代码。但同样,rm -rfcurl | bash、访问生产数据库也都可以做。

Claude Code 没有因为这种风险就限制 shell 能力,而是把 shell 做成了一个正式的工具,带权限、带语义识别、带任务管理。

命令语义识别

BashTool 在执行之前会先分析命令的语义:这是只读命令还是有副作用的命令?

grepfindcatls 这类命令被识别为只读操作,可以直接执行,结果在界面上也会自动折叠,不撑开会话流。

rmmv、写文件、启动服务这类命令被识别为有副作用,会触发权限检查,可能需要用户确认。

这个分类不是完美的,但它让权限系统可以对不同类型的命令有不同的默认策略,而不是一刀切。

长任务怎么处理

有些命令跑完要几分钟甚至更长。如果同步等待,整个会话就卡在那里了。

Claude Code 的处理方式是把 shell 命令纳入任务体系。每个长任务都有一个 task id,输出写到专门的文件里。你可以:

  • 让它在后台跑,继续做别的事
  • attach 重新连上去看实时输出
  • kill 终止它

默认超时是 2 分钟,最长可以给到 10 分钟。如果一条命令在 2 秒内没有产生任何输出,系统会考虑自动把它放到后台,不需要你手动操作。这样 shell 执行就从"等待返回"变成了"提交任务、查看进度",适合真正的长时间操作。

Sandbox 是另一层保护

除了权限规则,还有 sandbox 机制:某些命令可以在容器里执行,和主机环境隔离。

Sandbox 不是对所有命令都启用的,因为有性能成本。什么时候启用、启用哪种级别的隔离,取决于命令类型和当前的权限模式。权限规则和 sandbox 是两个独立的机制,可以组合使用:权限规则决定"这条命令允不允许运行",sandbox 决定"运行时有没有隔离"。

为什么不直接让模型自己组装 shell 命令

理论上可以:模型直接生成 shell 命令,通过 exec 执行,结果以文本返回。简单直接。

但这样做,系统对 shell 执行这件事完全没有感知。没有权限检查,没有任务管理,没有展示逻辑,没有长任务处理。出了问题,什么都捞不到。

把 shell 做成正式工具的代价是多了一层抽象,好处是 shell 执行变得可控、可见、可管理——这在 coding agent 里是刚需,不是可选功能。