-p:把 Claude Code 当 Unix 工具用
-p(即 --print)让 Claude Code 非交互运行:执行完任务直接退出, 成功退出码 0、失败非 0,脚本可以直接分支。stdin 可以进管道(上限 10MB,超了会明确报错退出):
# 问一个代码库问题
claude -p "What does the auth module do?"
# 管道:解释构建错误
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt官方文档给的「项目专属 lint」思路,把 Claude 变成 package.json 里的一个脚本:
{
"scripts": {
"lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
}
}把 diff 用管道喂进去而不是让 Claude 自己跑 git,好处是任务不需要授权 Bash 工具——权限面更小。
--bare:CI 必加的一个标志
默认情况下 claude -p 会加载与交互会话相同的上下文:hooks、skills、自定义命令、subagents、 插件、MCP 服务器、auto memory 和 CLAUDE.md。这在 CI 里是两个问题:
- 可重复性:同事 ~/.claude 里的一个 hook、项目 .mcp.json 里的一个服务器,都会让同一命令在不同机器上行为不同。
- 安全:官方明确提示,不加 --bare 时 -p 会话会执行项目 .claude/settings.json 里的 hooks、连接 .mcp.json 里的服务器,即使这个目录你从未信任过——-p 没有工作区信任弹窗,也没有逐服务器审批。
claude --bare -p "Summarize README.md" --allowedTools "Read"--bare 跳过上述全部自动发现,启动更快,且不读 OAuth 凭证和系统钥匙串——所以要提供ANTHROPIC_API_KEY(或走 Bedrock / Vertex / Foundry 的云凭证)。需要上下文就显式传:--append-system-prompt、--settings、--mcp-config、--agents。 官方说明 --bare 是脚本与 SDK 调用的推荐模式,并将在未来版本成为 -p 的默认行为。
输出格式:json 与 --json-schema
| 格式 | 内容 | 适合 |
|---|---|---|
text(默认) | 纯文本回答 | 人看 |
json | 结果 + 会话 ID + 用量与 total_cost_usd | 脚本消费、成本记录 |
stream-json | 逐行 JSON 事件流 | 实时进度、日志采集 |
要求固定字段时,给 --json-schema 一个 JSON Schema,结果出现在 structured_output 字段:
claude -p "Extract the main function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'无效 schema 会直接报错退出(2.1.205 起;更早版本会静默忽略)。流式细节:stream-json 要配--verbose --include-partial-messages 才有逐 token 事件;首个 system/init 事件里带mcp_server_errors 与 plugin_errors 字段,CI 可以对非空数组直接判失败,防止「服务器没连上但任务照样跑完」的假成功。
权限:白名单语法与三种模式
-p 会话的起始权限模式在所有套餐上都是 Manual,所以自动化必须显式给权限。第一种方式是精确白名单:
claude -p "Look at my staged changes and create an appropriate commit" \
--allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"规则语法支持前缀匹配:Bash(git diff *) 放行一切以 git diff 开头的命令。星号前的空格是语义的一部分——写成 git diff* 会连 git diff-index 一起放行。
第二种方式是设整体基线,三个可选模式:
--permission-mode auto:分类器代替人审大多数动作,适合半自动场景。--permission-mode dontAsk:白名单与只读命令集之外一律拒绝,适合锁死的 CI。--permission-mode acceptEdits:放行文件写入和 mkdir / mv / cp 等常见文件系统命令,其余 Bash 与网络请求仍需白名单。
GitHub Actions:@claude 与自动化两种模式
claude-code-action 按 workflow 是否提供 prompt 输入自动区分两种模式:不提供则为交互模式,等 issue / PR 里的 @claude 提及;提供则为自动化模式,事件一来就跑(定时任务、issue 自动分诊等)。
安装
- 快速通道:本地 Claude Code 里运行
/install-github-app,按提示装 App、存密钥、生成 workflow PR。 - 手动通道:装 Claude GitHub App,加密钥,复制官方 examples/claude.yml 到 .github/workflows/。
密钥怎么选
| 密钥 | 来源 | 适合 |
|---|---|---|
ANTHROPIC_API_KEY | Claude Console 创建 | 组织共享、按量计费、可审计 |
CLAUDE_CODE_OAUTH_TOKEN | 本地 claude setup-token 生成(Pro / Max / Team / Enterprise) | 个人仓库,用订阅额度跑 CI |
组织级共享密钥官方建议 API key:OAuth token 绑定生成者本人的订阅,人一离职或降档,全组织的 CI 一起失效。完全不想存长期密钥的团队可以走 OIDC 联邦(workload identity federation),用anthropic_federation_rule_id 等输入换短期凭证,workflow 需要 id-token: write 权限。
最小可用 workflow
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
claude:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}用订阅 token 时把最后一行换成 claude_code_oauth_token。之后在 issue 或 PR 里 @claude 提需求即可:修 bug、实现小功能、回答架构问题,Claude 会在同一个 issue / PR 下回帖并随进度更新。
谁能触发:两道内置校验
- 写权限校验:issue / PR 事件的触发者必须有仓库写权限;要放行外部贡献者需配
allowed_non_write_users并传自己的 github_token。 - 真人校验:机器人账号默认被拒(防循环触发),需要机器人触发时列入
allowed_bots;定时任务会被 GitHub 归属到最后改 cron 的用户,若那是个 bot 也要加白。
权限敏感的组织还可以不用官方 App 的全量权限集,按官方 setup 文档自建仅含 Contents / Issues / Pull requests 三项权限的自定义 GitHub App——代价是 Code Review、web auto-fix 等其他功能仍需官方 App。
成本与安全清单
- 每次无头调用记录 json 输出里的 total_cost_usd(客户端估算,对账看用量面板)。
- CI 任务默认 --bare + dontAsk / 精确白名单,杜绝隐式加载与越权命令。
- 给自动化任务设 --max-turns 类上限与超时,防失控长跑。
- 对 system/init 的 mcp_server_errors、plugin_errors 做非空即失败的门禁。
- API key 只放仓库 / 组织密钥,绝不进 workflow 明文;退役密钥要在 Console 同步删除,删 GitHub secret 不会使凭证失效。
无头模式的价值不在「省一次人工」,而在把 Claude 变成基础设施:typo lint、PR 分诊、失败构建解释、 周期性代码巡检,都是一条命令加一个 cron 的事。先从只读任务开始,跑顺了再逐步放开写权限。