用法
claude -p 用法详解:在脚本和 CI 里非交互运行 Claude Code
这一页讲怎么在脚本里用 claude -p 调用 Claude Code:基本用法、管道输入、三种输出格式、工具权限、续接对话和 bare 模式,命令都可以直接复制。参数、字段和行为取自 Anthropic 官方的 Run Claude Code programmatically 文档,2026 年 10 月 30 日核对。这里是一个精选,文档里还有子代理消息、后台任务等更多内容。
- 带上提示词传
-p(或--print)就是非交互运行。Claude Code 成功时退出码为 0,运行失败时为非 0,脚本可以据此分支。 --output-format可选text(默认)、json、stream-json。加上--json-schema会得到structured_output字段。- 在 Manual 模式的
claude -p运行里,需要批准的工具调用会被拒绝,除非有东西批准它。用--allowedTools列出工具,或用--permission-mode设基线。 - Anthropic 推荐脚本和 SDK 调用用
--bare:它跳过 hooks、skills、插件、MCP 服务器、auto memory 和CLAUDE.md的自动发现,每台机器上结果一致。
-p 做什么
在任何 claude 命令后加 -p(或 --print)标志,就以非交互方式运行。下面这条运行一个提示词并打印回复:
claude -p "What does the auth module do?"
不是每个 CLI 选项都能和 -p 组合。Claude Code 会拒绝 --bg,也会拒绝带任务描述的 --cloud,并给出指明冲突的错误。
Claude Code 成功时退出码为 0,运行失败时为非 0。如果传了无效的参数,它会在运行开始前把错误报告到 stderr。运行内部发生的失败,比如缺少认证,则作为结果打印在 stdout 上。
-p 可以和其他参数一起用。下面这条预先批准了三个工具,Claude 不用弹提示就能工作:
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
管道输入
非交互模式会读取 stdin,所以可以像其他命令行工具一样把数据管道进来,把回复重定向出去。下面把一份构建日志管道给 Claude,并把解释写进文件:
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
管道输入的 stdin 上限是 10MB。超过时,Claude Code 会报一个明确的错误并以非 0 状态退出。输入更大时,改为把内容写进文件,在提示词里引用文件路径。如果 Claude Code 读不了 stdin,比如启动它的进程断开了自己这一端,它会向 stderr 打印警告,并用命令行里的提示词继续。
也可以把调用包进脚本,把 Claude 当作项目专用的 linter。下面这个 package.json 脚本把相对 main 的 diff 管道给 Claude,让它报告拼写错误。管道传 diff 意味着 Claude 不需要 Bash 权限去读它,转义的双引号让脚本在 Windows 上也能用:
{
"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.\""
}
}
用 npm run lint:claude 运行。
输出格式
用 --output-format 控制回复的返回方式:
| 取值 | 得到什么 |
|---|---|
text(默认) | 纯文本输出 |
json | 结构化 JSON,包含结果、会话 ID 和元数据 |
stream-json | 以换行分隔的 JSON,用于实时流式输出 |
下面以 JSON 返回项目摘要,文本结果在 result 字段里:
claude -p "Summarize this project" --output-format json
用 --output-format json 时,返回内容里还有 total_cost_usd 和按模型拆分的费用,脚本可以据此跟踪花费。用 --continue 或 --resume 接着之前的对话时,这次运行报告的是整个对话的总额,包含之前几次运行的花费。这两个数字都是客户端估算,可能和实际账单不同。
可以用 jq 之类的工具取出具体字段:
# Extract the text result
claude -p "Summarize this project" --output-format json | jq -r '.result'
# Extract structured output
claude -p "Extract function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
用 JSON Schema 得到结构化输出
要让输出符合某个特定 schema,把 --output-format json 和 --json-schema 以及一份 JSON Schema 定义一起用。返回内容包含请求的元数据(会话 ID、用量等),结构化输出在 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"]}'
如果传入的值不是合法的 JSON Schema,claude 会以 Error: --json-schema is not a valid JSON Schema 退出,后面跟着校验器的诊断。Claude Code 接受使用 format 关键字的 schema,比如 "format": "email",但只把 format 当作注解,不强制执行。如果运行结束时没有有效的结构化输出,比如 Claude 拒绝了请求,返回内容里就没有 structured_output 字段,所以脚本使用它之前要先检查这个字段是否存在。
流式输出
用 --output-format stream-json 加 --verbose 和 --include-partial-messages,可以在 token 生成时就收到。每一行是一个表示事件的 JSON 对象:
claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages
流的最后一行是 result 消息,包含最终回复文本、费用和会话元数据。下面这个 jq 过滤器只保留文本增量;-r 输出原始字符串(不带引号),-j 不加换行地拼接,token 就能连续流出:
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'
system/init 事件报告会话元数据,包括模型、工具、MCP 服务器和已加载的插件。API 请求遇到可重试的错误时,Claude Code 会在重试前发出 system/api_retry 事件,字段包括 attempt、max_retries、retry_delay_ms 和 error_status。用 stream-json 时,被拒绝的调用会以 permission_denied 系统消息出现,最终的 result 消息会在 permission_denials 里列出它们。
非交互模式下的工具权限
没有人能回答权限提示,所以要事先决定 Claude 能做什么。用 --allowedTools 让 Claude 不经提示就使用某些工具。列出 Read 和 Edit,Claude 就能不问权限地读写文件,网络路径的读取除外。列出 Bash 对 shell 命令效果相同,但在以 auto 模式启动的运行里,Claude Code 会把单独的 Bash 条目当作过宽的 allow 规则丢弃,由 auto 模式逐条评估命令。下面列出这三个工具,运行测试套件并修复失败:
claude -p "Run the test suite and fix any failures" \
--allowedTools "Bash,Read,Edit"
没列出的工具,如果不需要批准,调用照样运行。在 Manual 模式的 claude -p 运行里,需要批准的调用会被拒绝,除非有东西批准它,比如 PermissionRequest hook 或 --permission-prompt-tool。Claude Code v2.1.302 及以后,没有任何设置指定权限模式时,claude -p 以 Manual 模式启动。
要把工具限制在特定命令上,--allowedTools 用的是权限规则语法。结尾的 * 启用前缀匹配,所以 Bash(git diff *) 允许任何以 git diff 开头的命令。* 前的空格很重要:没有它,Bash(git diff*) 还会匹配 git diff-index。
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 *)"
想给整个会话设一个基线,而不是逐个列工具,用 --permission-mode 传一个权限模式:
| 模式 | 在 -p 运行里的行为 |
|---|---|
auto | 由分类器代替你审查大部分操作 |
dontAsk | Claude Code 拒绝所有本来会弹出提示的调用,适合锁死的 CI 运行。Manual 模式下不需要批准的操作照常运行,被你的 --allowedTools 条目或 permissions.allow 规则覆盖的操作也照常运行 |
acceptEdits | Claude 不经提示写文件,Claude Code 自动批准 mkdir、touch、mv、cp 这类常见的文件系统命令。其他 shell 命令和网络请求仍然需要 --allowedTools 条目或 permissions.allow 规则 |
claude -p "Apply the lint fixes" --permission-mode acceptEdits
无人值守的任务里,没有人能回答权限提示时(比如定时任务)传 --permission-prompts none。任何会弹提示的操作都被拒绝,除非有 PermissionRequest hook 允许;Claude 会被告知没有人能批准这个请求、不要重试,运行继续。这个参数需要 Claude Code v2.1.259 及以后,更早的版本会以未知选项错误拒绝它。
claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none
各个模式本身的说明见 Claude Code 权限模式。
续接对话
用 --continue 继续最近的一次对话,或用 --resume 加会话 ID 继续指定的对话。下面先做一次审查,再发送后续提示:
# First request
claude -p "Review this codebase for performance issues"
# Continue the most recent conversation
claude -p "Now focus on the database queries" --continue
claude -p "Generate a summary of all issues found" --continue
同时跑多个对话时,记下会话 ID,就能恢复指定的那一个:
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
这两条命令可以在不同目录里运行:Claude Code 会按 ID 在本机任何项目里找到这个会话。除了会话 ID,也可以给 --resume 传某个会话 .jsonl 转录文件的绝对路径,Claude Code 会继续该文件里保存的对话。
给脚本和 CI 用的 bare 模式
加 --bare 可以缩短启动时间,它跳过 hooks、skills、自定义命令、子代理、已安装插件、MCP 服务器、auto memory 和 CLAUDE.md 的自动发现。不加的话,claude -p 会像交互会话一样发现并加载它们,包括工作目录或 ~/.claude 里配置的任何内容。bare 模式适合需要每台机器结果一致的 CI 和脚本:同事 ~/.claude 里的 hook,或项目 .mcp.json 里的 MCP 服务器都不会运行,因为 bare 模式根本不读它们。
运行下面这条之前先设置 ANTHROPIC_API_KEY,因为 bare 模式不使用你的订阅登录。它预先批准了 Read 工具,调用不用弹权限提示就能完成:
claude --bare -p "Summarize README.md" --allowedTools "Read"
在 bare 模式下,Claude Code 从不读取 OAuth 凭据或系统钥匙串。使用 Anthropic API 时,在环境里设置 ANTHROPIC_API_KEY(密钥在 Claude Console 创建),或者在 --settings 的 JSON 里提供 apiKeyHelper。Amazon Bedrock、Google Cloud 的 Agent Platform 和 Microsoft Foundry 照常读取各自的提供方凭据。
bare 模式下 Claude 可以使用 Bash、文件读取和文件编辑工具。需要的上下文用参数传入:
| 要加载 | 用 |
|---|---|
| 系统提示词补充 | --append-system-prompt、--append-system-prompt-file |
| 设置 | --settings <file-or-json> |
| MCP 服务器 | --mcp-config <file-or-json> |
| 自定义代理 | --agents <file-or-json> |
| 插件 | --plugin-dir <path>、--plugin-url <url> |
不加 --bare 时,-p 会话会运行项目 .claude/settings.json 里的 hooks,并连接 .mcp.json 里的服务器,即使是你从没信任过的文件夹。-p 会话不显示工作区信任对话框,也没有逐个服务器的批准提示。在不是自己写的仓库里运行 claude -p 之前,要想到这一点。文档说 --bare 是脚本和 SDK 调用的推荐模式,将来的版本会把它设为 -p 的默认。
其他用法
用 --append-system-prompt 可以在保留 Claude Code 默认行为的同时追加指令。下面把 PR 的 diff 管道给 Claude,让它做安全审查。存成 shell 脚本,比如 review.sh,运行 bash review.sh 123,shell 会把 "$1" 替换成 123:
gh pr diff "$1" | claude -p \
--append-system-prompt "You are a security engineer. Review for vulnerabilities." \
--output-format json
--system-prompt 会完全替换默认提示词。替换之后,运行也不再带 git status 快照。
-p 模式下命令的支持情况不同。用户调用的 skills 和自定义命令可以用:在提示词字符串里写 /skill-name,Claude Code 会在运行前展开它。只能在终端界面里运行的内置命令,比如 /login,不可用。要改设置,给 /config 传 key=value,例如 /config thinking=false。交互模式的命令见 Claude Code 常用命令大全。想在 GitHub 工作流里跑 claude -p,见 Claude Code 与 GitHub Actions。
故障排查
| 现象 | 文档怎么说 |
|---|---|
| 传了无效参数 | Claude Code 在运行开始前把错误报告到 stderr |
| 缺少认证 | 属于运行内部的失败,Claude Code 把它作为结果打印在 stdout 上 |
用 --bare 时认证失败 | bare 模式不使用订阅登录,从不读取 OAuth 凭据或系统钥匙串。设置 ANTHROPIC_API_KEY,或在 --settings 的 JSON 里提供 apiKeyHelper |
| 报错指出参数冲突 | -p 会拒绝 --bg,也拒绝带任务描述的 --cloud |
| 工具调用被拒绝 | 在 Manual 模式的运行里,需要批准的调用会被拒绝,除非有东西批准它。把它加进 --allowedTools,或设置 --permission-mode |
--permission-prompts 报未知选项错误 | 这个参数需要 Claude Code v2.1.259 及以后 |
Error: --json-schema is not a valid JSON Schema | 传入的值不是合法的 JSON Schema,信息后面跟着校验器的诊断 |
没有 structured_output 字段 | 运行结束时没有有效的结构化输出,比如 Claude 拒绝了请求。先检查该字段是否存在 |
| 管道传很大的文件失败 | 管道输入的 stdin 上限是 10MB。把内容写进文件,在提示词里写路径 |
| 配置的 MCP 服务器没出现 | Claude Code 会跳过校验失败的 --mcp-config 条目,运行照常正常退出。检查 system/init 事件里的 mcp_server_errors;没有错误时这个键会被省略,所以 CI 可以在数组非空时判失败 |
| Claude 回复完了,运行还不退出 | 它可能在等 Claude 启动的后台任务。默认情况下,连续空闲等待 10 分钟后,Claude Code 会停掉仍在运行的内容。用 CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS 修改这个上限,设为 0 则不设上限地等待 |
| 退出码 143 | 你用 SIGTERM 停掉了运行。Claude Code 会让进行中的这一轮保持未完成,也不为它记录结果。想结束这一轮,先发 SIGINT 再停进程。想在恢复时继续被中断的一轮,设置 CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1 |
常见问题
-p 和 --print 一样吗?
一样。文档把这个标志写作 -p(或 --print),加在任何 claude 命令上都会变成非交互运行。
脚本里为什么我的编辑或命令被拒绝了?
-p 运行里没有人能回答权限提示。在 Manual 模式下,需要批准的调用会被拒绝,除非有东西批准它,比如 PermissionRequest hook 或 --permission-prompt-tool。用 --allowedTools 列出要用的工具,例如 --allowedTools "Bash,Read,Edit";只是改文件的话,也可以传 --permission-mode acceptEdits。
怎么让每台机器或每个 CI runner 上的结果一致?
加 --bare。它跳过宿主机上的 hooks、skills、插件、MCP 服务器、auto memory 和 CLAUDE.md,同事的 ~/.claude 或项目的 .mcp.json 就影响不到这次运行。先设置 ANTHROPIC_API_KEY,因为 bare 模式不使用订阅登录;需要的上下文用 --settings、--mcp-config 这类参数传入。
来源
- Claude Code:Run Claude Code programmatically(
-p、输出格式、权限、--bare、续接会话) - Claude Code:CLI reference(全部 CLI 参数和选项)
- Claude Code:Permission modes(每个
--permission-mode取值的作用)