Claude Code의 헤드리스 모드, 백그라운드 실행, --output-format json 스트리밍으로 장시간 자동화 작업을 안정적으로 제어하는 방법.
백그라운드 작업 — 기다리지 않고 실행하기
30분짜리 마이그레이션 작업, 전체 코드베이스 타입 오류 수정, 수백 개 파일의 번역 추가 — 이런 작업을 터미널 앞에 앉아서 기다리는 것은 비효율적입니다. Claude Code의 헤드리스 모드와 백그라운드 실행을 활용하면 작업을 시작하고 다른 일을 하면서 완료 알림을 받는 방식으로 운영할 수 있습니다.
헤드리스 모드 (--print / -p)
대화형 세션 없이 단일 프롬프트를 실행하고 종료합니다. 스크립트, CI, 크론 작업에 사용하는 기본 패턴입니다.
# 기본 헤드리스 실행
claude -p "package.json의 모든 의존성을 최신 버전으로 업데이트하고 테스트 통과 확인"
# JSON 출력으로 프로그램에서 결과 파싱 가능
claude -p "린트 오류 분석 후 JSON으로 파일별 오류 목록 반환" \
--output-format json \
> lint-report.json
# 허용 도구 제한
claude -p "타입 오류 모두 수정" \
--allowedTools "Read,Edit,Glob,Grep" \
--output-format stream-json
백그라운드 실행 패턴
# & 로 백그라운드 실행 (Unix)
claude -p "전체 i18n 번역 키 누락 검사 및 추가" \
--allowedTools "Read,Edit,Glob,Grep,Write" \
> i18n-update.log 2>&1 &
echo "작업 시작됨 (PID: $!)"
# 나중에 결과 확인
tail -f i18n-update.log
# Windows PowerShell
Start-Job -ScriptBlock {
claude -p "전체 i18n 번역 키 누락 검사 및 추가" `
--allowedTools "Read,Edit,Glob,Grep,Write" `
2>&1 | Out-File i18n-update.log
}
--output-format stream-json 활용
장시간 작업의 진행 상황을 실시간으로 모니터링하려면 스트리밍 JSON 형식을 사용합니다.
claude -p "500개 컴포넌트 접근성 감사" \
--output-format stream-json \
--allowedTools "Read,Glob,Grep" | \
while IFS= read -r line; do
# 각 이벤트 타입 파싱
type=$(echo "$line" | jq -r '.type // empty')
case "$type" in
"assistant")
text=$(echo "$line" | jq -r '.message.content[0].text // empty')
[ -n "$text" ] && echo "📝 $text"
;;
"result")
echo "✅ 완료: $(echo "$line" | jq -r '.result')"
;;
esac
done
Claude Code SDK로 프로그래밍 방식 제어
Node.js 스크립트에서 Claude Code를 직접 호출하는 방법입니다. 복잡한 자동화 파이프라인에서 조건 분기와 오류 처리가 필요할 때 사용합니다.
// run-automation.mjs
import Anthropic from "@anthropic-ai/sdk"
const client = new Anthropic()
async function runAutomation(task) {
console.log(`🚀 시작: ${task}`)
const startTime = Date.now()
const messages = []
for await (const event of client.messages.stream({
model: "claude-opus-4-5",
max_tokens: 8096,
messages: [{ role: "user", content: task }],
tools: [/* MCP 도구 목록 */]
})) {
if (event.type === "content_block_delta") {
process.stdout.write(".")
}
if (event.type === "message_stop") {
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1)
console.log(`\n✅ 완료 (${elapsed}s)`)
}
}
}
// 순차 실행 (의존성 있는 작업)
await runAutomation("DB 마이그레이션 파일 생성")
await runAutomation("TypeScript 타입 재생성")
await runAutomation("관련 컴포넌트 업데이트")
타임아웃과 재시도 처리
#!/bin/bash
# 타임아웃 30분, 실패 시 재시도
MAX_RETRIES=3
TIMEOUT=1800 # 30분
for i in $(seq 1 $MAX_RETRIES); do
echo "시도 $i/$MAX_RETRIES..."
timeout $TIMEOUT claude -p "$TASK" \
--allowedTools "Read,Edit,Bash" \
--dangerouslySkipPermissions \
> "output-attempt-$i.log" 2>&1
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "✅ 성공"
break
elif [ $EXIT_CODE -eq 124 ]; then
echo "⏰ 타임아웃 — 재시도..."
else
echo "❌ 오류 (코드: $EXIT_CODE) — 재시도..."
fi
sleep 5
done
작업 분할로 타임아웃 방지
한 번에 너무 큰 작업은 중간에 타임아웃이 발생합니다. 파일 목록을 나누어 여러 번 실행하는 것이 안정적입니다.
#!/bin/bash
# 파일 목록을 10개씩 나누어 처리
find app -name "*.tsx" | split -l 10 - batch-
for batch_file in batch-*; do
files=$(cat "$batch_file" | tr '\n' ' ')
claude -p "다음 파일들의 TypeScript 오류 수정: $files" \
--allowedTools "Read,Edit" \
>> fix-all.log 2>&1
rm "$batch_file"
done
백그라운드 자동화의 핵심 원칙: 작업을 믿을 수 있어야 한다. 이를 위해 모든 출력을 로그 파일에 저장하고, 완료 여부를 프로그래밍으로 확인하며, 실패 시 재시도 로직을 갖추어야 합니다. 30분 후 컴퓨터로 돌아왔을 때 "뭘 했는지" 알 수 있어야 자동화를 신뢰하고 사용하게 됩니다.
핵심 정리
- -p(헤드리스) + & 백그라운드 실행으로 긴 작업을 터미널에서 분리 — 진행 로그를 파일로 저장해 나중에 확인
- --output-format stream-json으로 실시간 진행 파싱 — 조건 분기·알림 연동에 활용
- 큰 작업은 배치 분할 + 타임아웃 재시도 패턴으로 안정성 확보 — 실패해도 중간부터 이어서 실행 가능하도록 설계
관련 검색어 · 클로드 코드 · Claude Code · 백그라운드 실행 · 장시간 자동화 · stream-json · 자동화 모니터링 · 클로드 코드 파이프라인