第 6 章 Shell 执行
Shell 是最强也是最危险的能力
给 agent 开放 shell,它就能做几乎任何事:跑测试、安装依赖、启动服务、部署代码。但同样,rm -rf、curl | bash、访问生产数据库也都可以做。
Claude Code 没有因为这种风险就限制 shell 能力,而是把 shell 做成了一个正式的工具,带权限、带语义识别、带任务管理。
命令语义识别
BashTool 在执行之前会先分析命令的语义:这是只读命令还是有副作用的命令?
grep、find、cat、ls 这类命令被识别为只读操作,可以直接执行,结果在界面上也会自动折叠,不撑开会话流。
rm、mv、写文件、启动服务这类命令被识别为有副作用,会触发权限检查,可能需要用户确认。
这个分类不是完美的,但它让权限系统可以对不同类型的命令有不同的默认策略,而不是一刀切。
长任务怎么处理
有些命令跑完要几分钟甚至更长。如果同步等待,整个会话就卡在那里了。
Claude Code 的处理方式是把 shell 命令纳入任务体系。每个长任务都有一个 task id,输出写到专门的文件里。你可以:
- 让它在后台跑,继续做别的事
- 用
attach重新连上去看实时输出 - 用
kill终止它
默认超时是 2 分钟,最长可以给到 10 分钟。如果一条命令在 2 秒内没有产生任何输出,系统会考虑自动把它放到后台,不需要你手动操作。这样 shell 执行就从"等待返回"变成了"提交任务、查看进度",适合真正的长时间操作。
Sandbox 是另一层保护
除了权限规则,还有 sandbox 机制:某些命令可以在容器里执行,和主机环境隔离。
Sandbox 不是对所有命令都启用的,因为有性能成本。什么时候启用、启用哪种级别的隔离,取决于命令类型和当前的权限模式。权限规则和 sandbox 是两个独立的机制,可以组合使用:权限规则决定"这条命令允不允许运行",sandbox 决定"运行时有没有隔离"。
为什么不直接让模型自己组装 shell 命令
理论上可以:模型直接生成 shell 命令,通过 exec 执行,结果以文本返回。简单直接。
但这样做,系统对 shell 执行这件事完全没有感知。没有权限检查,没有任务管理,没有展示逻辑,没有长任务处理。出了问题,什么都捞不到。
把 shell 做成正式工具的代价是多了一层抽象,好处是 shell 执行变得可控、可见、可管理——这在 coding agent 里是刚需,不是可选功能。