CoreCode部落格

用法

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由分類器代替你審查大部分操作
dontAskClaude Code 拒絕所有本來會彈出提示的呼叫,適合鎖死的 CI 執行。Manual 模式下不需要批准的操作照常執行,被你的 --allowedTools 條目或 permissions.allow 規則覆蓋的操作也照常執行
acceptEditsClaude 不經提示寫檔案,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 這類引數傳入。

來源