Claude Code 学习站

Claude Code 无头模式完全指南:用 -p 驱动脚本与 CI/CD 自动化

介绍如何通过 claude -p 以非交互方式运行 Claude Code,涵盖 --bare 模式、结构化输出、流式响应、工具权限、多轮对话等核心用法,适合嵌入 CI/CD 与自动化脚本的开发者。

本页目录14
要点速览
  • 加 -p 标志即可进入非交互模式,所有 CLI 选项均可配合使用
  • --bare 模式跳过 hooks/插件/CLAUDE.md 等自动发现流程,推荐用于 CI 脚本以保证结果可复现
  • --output-format json 返回含成本数据的结构化响应,配合 --json-schema 可强制输出符合特定 schema 的结果
  • --output-format stream-json 支持实时 token 流,含 api_retry 和 init 等系统事件
  • --allowedTools 和 --permission-mode 控制工具权限,dontAsk/acceptEdits 两种预设适合不同 CI 场景
  • --continue 与 --resume 支持多轮对话,session_id 可跨调用追踪会话

本文是对官方文档「Run Claude Code programmatically」的中文要点摘要,完整内容以原文为准。原文链接:https://code.claude.com/docs/en/headless

一句话概览

通过 -p(--print)标志,可以将 Claude Code 以非交互方式嵌入脚本、CI/CD 流水线或自动化构建流程中。底层能力由 Agent SDK 提供,与交互模式共用相同的工具、Agent 循环和上下文管理机制。

基础用法

在任何 claude 命令后加上 -p <提示词> 即可进入非交互模式:

claude -p 'Find and fix the bug in auth.py' --allowedTools 'Read,Edit,Bash'

所有 CLI 选项均可与 -p 配合使用,包括 --continue--allowedTools--output-format 等。

--bare 模式:CI 脚本推荐选项

加上 --bare 后,Claude Code 会跳过 hooks、skills、插件、MCP 服务、auto memory 和 CLAUDE.md 的自动加载,从而加快启动速度并保证每台机器执行结果一致,避免本地配置污染 CI 输出。

  • 认证必须通过 ANTHROPIC_API_KEY 环境变量或 --settings 中的 apiKeyHelper 提供(不走 OAuth/keychain)
  • 若需额外上下文,可用如下标志按需注入:
目的标志
追加系统提示--append-system-prompt / --append-system-prompt-file
设置文件--settings <file-or-json>
MCP 服务--mcp-config <file-or-json>
自定义 Agent--agents <json>
插件--plugin-dir <path> / --plugin-url <url>

官方提示:--bare 是脚本/SDK 调用的推荐模式,未来版本将成为 -p 的默认行为。

后台任务的生命周期

  • claude -p 返回最终结果并关闭 stdin 后,后台 Bash 任务约在 5 秒内被终止(v2.1.163 之前会永久阻塞)
  • 后台子 Agent / Workflow 会等待完成,因为其结果属于最终输出的一部分
  • v2.1.182 起,后台等待上限默认为 10 分钟,可通过环境变量 CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS 调整(设为 0 表示无限等待)

常用场景示例

管道(Pipe)输入

非交互模式读取 stdin,可像普通命令行工具一样处理管道数据:

cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt

注意:v2.1.128 起,管道 stdin 上限为 10 MB,超出则以非零状态码退出,建议改为传文件路径。

嵌入构建脚本

package.json 中把 Claude 用作拼写检查 linter:

{
  "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.\""
  }
}

获取结构化输出

--output-format json 返回含 resultsession_idtotal_cost_usd 等字段的 JSON 对象。搭配 --json-schema 可强制输出符合特定 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 解析输出:

claude -p 'Summarize this project' --output-format json | jq -r '.result'

流式输出

--output-format stream-json 配合 --verbose --include-partial-messages 可实时接收 token 流,每行是一个 JSON 事件对象。流中包含两类关键系统事件:

  • system/api_retry:API 请求失败并即将重试时发出,含 attemptmax_retriesretry_delay_mserror 等字段,可用于自定义退避逻辑
  • system/init:流中的第一个事件,包含 session 元数据(model、tools、MCP servers、已加载插件及插件错误),可用于 CI 中检测插件是否成功加载。例外情形:当设置了 CLAUDE_CODE_SYNC_PLUGIN_INSTALL 环境变量时,plugin_install 事件会先于 system/init 出现

jq 过滤 text_delta 事件实现实时文字流:

claude -p 'Write a poem' --output-format stream-json --verbose --include-partial-messages | \
  jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'

自动批准工具权限

--allowedTools 列举无需用户确认的工具;--permission-mode 设置整个 session 的基线权限:

模式行为
dontAsk拒绝所有未在 permissions.allow 或只读命令集中的工具,适合严格 CI
acceptEdits允许写文件,并自动批准 mkdirtouchmvcp 等常见文件系统命令
claude -p 'Apply the lint fixes' --permission-mode acceptEdits

自动创建 Git Commit

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 *) 中结尾的「空格 + *」表示前缀匹配;不带空格写成 Bash(git diff*) 则会误匹配 git diff-index,需注意区分。

自定义系统提示

--append-system-prompt 在保留 Claude Code 默认行为的同时追加指令;--system-prompt 则完全替换默认提示:

gh pr diff "$1" | claude -p \
  --append-system-prompt 'You are a security engineer. Review for vulnerabilities.' \
  --output-format json

多轮对话

--continue 继续最近一次对话;--resume <session_id> 恢复指定会话(查找范围限定在当前项目目录及其 git worktree):

# 首次调用
claude -p 'Review this codebase for performance issues'

# 继续上一次对话
claude -p 'Now focus on the database queries' --continue

# 用 session_id 恢复特定会话
session_id=$(claude -p 'Start a review' --output-format json | jq -r '.session_id')
claude -p 'Continue that review' --resume "$session_id"

延伸阅读

  • Agent SDK 快速入门(Python / TypeScript 包,支持结构化输出、工具回调、原生消息对象)
  • CLI 参考手册(完整 flag 列表)
  • GitHub Actions / GitLab CI/CD 集成指南