가이드
claude -p 가이드: 스크립트와 CI에서 Claude Code를 비대화형으로 실행하기
이 글은 claude -p로 스크립트에서 Claude Code를 호출하는 사용법을 보여 줍니다. 기본 사용법, 입력 파이프, 세 가지 출력 형식, 도구 권한, 대화 이어 가기, bare 모드를 다루며, 각각 복사해서 쓸 수 있는 명령어를 함께 실었습니다. 플래그, 필드, 동작은 Anthropic의 Run Claude Code programmatically 문서를 2026년 10월 30일에 확인한 내용입니다. 일부만 골라 실었고, 문서에는 subagent 메시지와 백그라운드 작업 같은 내용이 더 있습니다.
- 프롬프트와 함께
-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 서버, 자동 메모리,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을 읽으므로 다른 명령줄 도구처럼 데이터를 파이프로 넣고 응답을 리다이렉트할 수 있습니다. 아래 명령은 빌드 로그를 파이프로 넣고 설명을 파일에 씁니다.
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를 프로젝트 전용 린터로 쓸 수도 있습니다. 이 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 | 결과, 세션 ID, 메타데이터를 담은 구조화된 JSON |
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로 구조화된 출력 받기
특정 스키마에 맞는 출력을 얻으려면 --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": "email" 같은 format 키워드를 쓰는 스키마를 받아들이지만, format을 주석으로만 취급하고 강제하지는 않습니다. Claude가 요청을 거절한 경우처럼 유효한 구조화된 출력 없이 실행이 끝나면 응답에 structured_output 필드가 없으므로, 스크립트에서 쓰기 전에 그 필드가 있는지 확인하세요.
스트리밍
토큰이 생성되는 대로 받으려면 --output-format stream-json에 --verbose와 --include-partial-messages를 함께 사용합니다. 각 줄은 이벤트를 나타내는 JSON 객체입니다.
claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages
스트림의 마지막 줄은 최종 응답 텍스트, 비용, 세션 메타데이터를 담은 result 메시지입니다. 아래 jq 필터는 텍스트 델타만 남깁니다. -r은 따옴표 없는 원시 문자열을 출력하고 -j는 줄바꿈 없이 이어 붙여 토큰이 끊김 없이 스트리밍되게 합니다.
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를 나열하면 셸 명령에도 같은 효과가 있지만, auto 모드로 시작하는 실행에서는 예외입니다. 이 경우 Claude Code는 단독 Bash 항목을 광범위한 허용 규칙으로 보고 버리며, 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 같은 일반적인 파일 시스템 명령을 자동 승인합니다. 다른 셸 명령과 네트워크 요청은 여전히 --allowedTools 항목이나 permissions.allow 규칙이 필요합니다 |
claude -p "Apply the lint fixes" --permission-mode acceptEdits
예약 작업처럼 권한 프롬프트에 답할 사람이 없는 무인 작업에는 --permission-prompts none을 전달하세요. 프롬프트를 띄웠을 모든 것은 PermissionRequest hook이 허용하지 않는 한 거부되고, Claude는 아무도 요청을 승인할 수 없으니 재시도하지 말라는 안내를 받으며, 실행은 계속됩니다. 이 플래그는 Claude Code v2.1.259 이상이 필요하며, 이전 버전은 unknown-option 오류로 거부합니다.
claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none
모드 자체는 Claude Code 권한 모드에서 설명합니다.
대화 이어 가기
가장 최근 대화를 이어 가려면 --continue를, 특정 대화를 이어 가려면 세션 ID와 함께 --resume을 사용합니다. 아래 명령은 리뷰를 실행한 뒤 후속 프롬프트를 보냅니다.
# 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 대신 세션의 .jsonl 트랜스크립트 파일의 절대 경로를 --resume에 전달할 수도 있으며, 그러면 Claude Code는 그 파일에 저장된 대화를 이어 갑니다.
스크립트와 CI를 위한 bare 모드
--bare를 추가하면 hooks, skills, 커스텀 명령어, subagent, 설치된 플러그인, MCP 서버, 자동 메모리, CLAUDE.md의 자동 검색을 건너뛰어 시작 시간이 줄어듭니다. 이 플래그가 없으면 claude -p는 작업 디렉터리나 ~/.claude에 설정된 것을 포함해 대화형 세션처럼 그것들을 찾아 로드합니다. bare 모드는 어느 머신에서나 같은 결과가 필요한 CI와 스크립트에 유용합니다. 동료의 ~/.claude에 있는 hook이나 프로젝트 .mcp.json의 MCP 서버는 bare 모드가 읽지 않으므로 실행되지 않습니다.
bare 모드는 구독 로그인을 사용하지 않으므로 실행하기 전에 ANTHROPIC_API_KEY를 설정하세요. 아래 명령은 Read 도구를 미리 승인해 권한 프롬프트 없이 호출이 끝나게 합니다.
claude --bare -p "Summarize README.md" --allowedTools "Read"
bare 모드에서 Claude Code는 OAuth 자격 증명이나 시스템 키체인을 읽지 않습니다. Anthropic API에는 Claude Console에서 만든 키를 환경 변수 ANTHROPIC_API_KEY로 설정하거나, --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의 기본값이 될 것이라고 밝힙니다.
기타 활용법
Claude Code의 기본 동작을 유지하면서 지침을 추가하려면 --append-system-prompt를 사용하세요. 아래 명령은 PR diff를 Claude에 파이프로 넣고 보안 리뷰를 요청합니다. review.sh 같은 셸 스크립트로 저장해 bash review.sh 123으로 실행하면 셸이 "$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 thinking=false처럼 /config에 key=value를 전달하세요. 대화형 명령어는 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에서 unknown-option 오류 | 이 플래그는 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가 시작한 백그라운드 작업을 기다리는 중일 수 있습니다. 기본적으로 Claude Code는 연속 10분간 유휴 대기하면 아직 실행 중인 것을 중지합니다. 상한을 바꾸려면 CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS를 설정하고, 상한 없이 기다리려면 0으로 설정하세요 |
| 종료 코드 143 | SIGTERM으로 실행을 멈춘 것입니다. Claude Code는 진행 중인 턴을 끝내지 않고 그에 대한 결과도 기록하지 않습니다. 대신 턴을 끝내려면 프로세스를 멈추기 전에 SIGINT를 보내세요. 재개할 때 중단된 턴을 이어 가려면 CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1을 설정하세요 |
FAQ
-p와 --print는 같은 건가요?
네. 문서는 이 플래그를 -p(또는 --print)로 설명하며, 어떤 claude 명령이든 비대화형 실행으로 바꿔 줍니다.
스크립트에서 편집이나 명령이 왜 거부되었나요?
-p 실행에서는 아무도 권한 프롬프트에 답할 수 없습니다. Manual 모드에서 승인이 필요한 호출은 PermissionRequest hook이나 --permission-prompt-tool 같은 무언가가 승인하지 않으면 거부됩니다. 원하는 도구를 --allowedTools "Bash,Read,Edit"처럼 --allowedTools로 나열하거나, 파일 편집에는 --permission-mode acceptEdits를 전달하세요.
어느 머신이나 CI 러너에서든 같은 결과를 얻으려면 어떻게 하나요?
--bare를 추가하세요. 호스트의 hooks, skills, 플러그인, MCP 서버, 자동 메모리, CLAUDE.md를 건너뛰므로 동료의 ~/.claude나 프로젝트의 .mcp.json이 실행을 바꾸지 못합니다. bare 모드는 구독 로그인을 사용하지 않으니 먼저 ANTHROPIC_API_KEY를 설정하고, 필요한 컨텍스트는 --settings나 --mcp-config 같은 플래그로 전달하세요.
출처
- Claude Code: Run Claude Code programmatically (
-p, 출력 형식, 권한,--bare, 세션 재개) - Claude Code: CLI reference (모든 CLI 플래그와 옵션)
- Claude Code: Permission modes (각
--permission-mode값의 동작)