-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_errorsplugin_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 自动分诊等)。

安装

  1. 快速通道:本地 Claude Code 里运行 /install-github-app,按提示装 App、存密钥、生成 workflow PR。
  2. 手动通道:装 Claude GitHub App,加密钥,复制官方 examples/claude.yml 到 .github/workflows/。

密钥怎么选

密钥来源适合
ANTHROPIC_API_KEYClaude 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。

成本与安全清单

  1. 每次无头调用记录 json 输出里的 total_cost_usd(客户端估算,对账看用量面板)。
  2. CI 任务默认 --bare + dontAsk / 精确白名单,杜绝隐式加载与越权命令。
  3. 给自动化任务设 --max-turns 类上限与超时,防失控长跑。
  4. 对 system/init 的 mcp_server_errors、plugin_errors 做非空即失败的门禁。
  5. API key 只放仓库 / 组织密钥,绝不进 workflow 明文;退役密钥要在 Console 同步删除,删 GitHub secret 不会使凭证失效。

无头模式的价值不在「省一次人工」,而在把 Claude 变成基础设施:typo lint、PR 分诊、失败构建解释、 周期性代码巡检,都是一条命令加一个 cron 的事。先从只读任务开始,跑顺了再逐步放开写权限。