클로드 코드 완전 자동화 #2 — cron으로 매시간 무인 실행하기
claude -p 헤드리스 모드 + crontab으로 Claude Code를 정기 실행하는 완전 무인 자동화 구성법.
한 줄 요약: claude -p로 헤드리스 실행 + crontab으로 정기 스케줄 = 완전 무인 자동화
클로드 코드를 터미널에서 직접 대화하는 것 외에도, 스크립트 안에서 호출하고 cron으로 정기적으로 실행하는 완전 자동화 방식이 있다. 이 글에서는 claude -p 헤드리스 모드 사용법부터 crontab 설정, macOS launchd와 Linux systemd timer 대안, 그리고 실전 자동화 스크립트 3가지를 다룬다.
- 클로드 코드를 사람이 없을 때도 자동으로 실행하고 싶은 개발자
- 매일 새벽 코드 품질 리포트, 로그 분석 등을 자동화하고 싶은 경우
- GitHub Actions와 Claude Code를 연동해 PR 자동 리뷰를 구성하려는 팀
- cron / launchd / systemd timer 중 어떤 방식을 써야 할지 결정하고 싶은 경우
※ 이 글은 2026년 3월 기준, Claude Code 공식 문서(docs.anthropic.com) 기반으로 작성됐습니다. 시리즈 3편 중 2편입니다.
claude -p로 스크립트에서 헤드리스 실행하기
클로드 코드는 기본적으로 대화형 REPL 인터페이스로 실행되지만, -p 플래그를 사용하면 프롬프트를 직접 전달해 단일 응답을 받고 종료하는 헤드리스(비대화형) 모드로 실행할 수 있다. 스크립트 안에 넣거나 cron으로 자동 실행할 때 사용하는 기본 방식이다.
기본 헤드리스 실행
가장 단순한 형태로 프롬프트를 직접 전달한다.
claude -p 기본 사용법# 프롬프트를 직접 인라인으로 전달 claude -p "현재 디렉토리의 TypeScript 파일에서 any 타입 사용을 모두 찾아서 목록으로 출력해줘" # stdin에서 프롬프트 파이핑 echo "package.json을 분석해서 보안 취약점이 있는 패키지를 찾아줘" | claude -p # 파일 내용을 프롬프트와 함께 파이핑 cat error.log | claude -p "이 로그에서 critical 에러만 추출해서 요약해줘"
허용 도구 지정
--allowedTools로 Claude Code가 사용할 수 있는 도구를 명시적으로 제한한다. 자동화 스크립트에서는 범위를 좁혀놓는 것이 안전하다.
--allowedTools로 사용 범위 제한# 파일 읽기·편집만 허용 (네트워크, 셸 명령어 차단) claude -p "src/ 폴더의 console.log를 모두 제거해줘" --allowedTools Read,Edit # 읽기·쓰기·Bash 허용 (가장 일반적인 자동화 조합) claude -p "테스트 커버리지 리포트를 생성해줘" --allowedTools Read,Write,Bash # 위험한 명령 차단하고 편집 권한만 claude -p "TODO 주석을 정리해줘" --allowedTools Read,Edit,Write
JSON 출력으로 결과 저장
자동화 파이프라인에서 Claude Code의 결과를 다음 단계로 넘기려면 --output-format json을 사용한다. 결과가 JSON 형식으로 출력되므로 jq로 파싱하거나 파일로 저장할 수 있다.
JSON 출력 및 파일 저장# JSON 형식으로 출력 claude -p "코드 리뷰 결과를 JSON으로 정리해줘" --output-format json # 결과를 파일로 저장 claude -p "의존성 분석" --output-format json > /tmp/analysis-$(date +%Y%m%d).json # jq로 응답 텍스트만 추출 claude -p "버그 목록" --output-format json | jq -r '.result'
claude 명령어를 그냥 쓰면 command not found가 발생한다. 반드시 절대경로를 사용할 것 — 예: /Users/username/.npm-global/bin/claude 또는 /usr/local/bin/claude. 절대경로는 which claude로 확인한다.crontab으로 정기 실행 설정하기
cron은 유닉스 계열 OS에서 내장 제공하는 작업 스케줄러다. 설정 파일(crontab)에 실행 주기와 명령어를 등록하면 백그라운드에서 자동으로 실행된다. 별도 설치 없이 macOS와 Linux 모두에서 동작한다.
crontab 기본 사용법
crontab 편집 및 확인# crontab 편집기 열기 crontab -e # 등록된 작업 목록 확인 crontab -l # 현재 사용자의 crontab 백업 crontab -l > ~/crontab-backup.txt # crontab 문법: 분 시 일 월 요일 명령어 # 예: 매일 새벽 2시에 실행 0 2 * * * /path/to/script.sh
cron 시간 표현식 핵심 패턴
| 표현식 | 의미 |
|---|---|
0 * * * * | 매시간 정각 |
0 2 * * * | 매일 새벽 2시 |
*/30 * * * * | 30분마다 |
0 9 * * 1-5 | 평일 오전 9시 |
0 0 * * 0 | 매주 일요일 자정 |
0 2 1 * * | 매월 1일 새벽 2시 |
로그 저장과 오류 기록
crontab에 Claude Code 스크립트 등록 (로그 포함)# crontab -e 에서 아래 형식으로 등록 # 1. PATH를 crontab 상단에 명시 PATH=/usr/local/bin:/usr/bin:/bin:/Users/username/.npm-global/bin # 2. 매시간 정각에 로그 분석 스크립트 실행 0 * * * * /Users/username/scripts/hourly-log-check.sh >> /var/log/claude-cron.log 2>&1 # 3. 매일 새벽 2시에 코드 품질 리포트 생성 0 2 * * * /Users/username/scripts/daily-code-report.sh >> /var/log/claude-daily.log 2>&1 # 4. 날짜별 로그 파일로 분리하려면 0 2 * * * /Users/username/scripts/daily-code-report.sh >> /var/log/claude-$(date +\%Y\%m\%d).log 2>&1
stdout)만 리다이렉트하고 2>&1을 빠뜨리면 에러 메시지가 어디에도 기록되지 않는다. 자동화 스크립트에서 뭔가 작동 안 할 때 로그를 봐도 아무것도 없는 가장 흔한 원인이다. >> /path/to/logfile 2>&1 패턴을 항상 붙이는 것을 원칙으로 할 것.실전 자동화 스크립트 예시 3가지
실제로 쓸 수 있는 자동화 스크립트 3가지를 전체 코드로 제공한다. 프로젝트 경로와 Claude Code 설치 경로는 각자 환경에 맞게 수정할 것.
예시 1: 매일 새벽 코드 품질 리포트 생성
daily-code-report.sh#!/bin/bash # 매일 새벽 2시 실행 — 코드 품질 리포트 생성 # crontab: 0 2 * * * /Users/username/scripts/daily-code-report.sh >> /var/log/claude-daily.log 2>&1 set -euo pipefail CLAUDE_BIN="/Users/username/.npm-global/bin/claude" PROJECT_DIR="/Users/username/projects/myapp" REPORT_DIR="/Users/username/reports" DATE=$(date +%Y%m%d) mkdir -p "$REPORT_DIR" cd "$PROJECT_DIR" echo "[$(date)] 코드 품질 리포트 시작" "$CLAUDE_BIN" -p " src/ 디렉토리의 TypeScript 파일을 분석해서 다음 항목을 리포트해줘: 1. any 타입 사용 횟수와 파일 목록 2. TODO/FIXME 주석 목록 3. 함수 길이가 50줄 이상인 파일 4. 중복 코드 패턴 결과는 마크다운 형식으로 작성해줘. " \ --allowedTools Read,Bash \ --output-format json | jq -r '.result' > "$REPORT_DIR/report-$DATE.md" echo "[$(date)] 리포트 저장 완료: $REPORT_DIR/report-$DATE.md"
예시 2: 매시간 로그 분석 + 이상 감지
hourly-log-check.sh#!/bin/bash # 매시간 정각 실행 — 최근 1시간 로그에서 이상 감지 # crontab: 0 * * * * /Users/username/scripts/hourly-log-check.sh >> /var/log/claude-cron.log 2>&1 CLAUDE_BIN="/usr/local/bin/claude" APP_LOG="/var/log/myapp/app.log" ALERT_FILE="/tmp/claude-alert-$(date +%Y%m%d%H).txt" # 최근 1시간치 로그를 임시 파일로 추출 LAST_HOUR_LOG=$(tail -n 1000 "$APP_LOG" | grep "$(date -v-1H '+%Y-%m-%dT%H')") if [ -z "$LAST_HOUR_LOG" ]; then echo "[$(date)] 최근 1시간 로그 없음, 스킵" exit 0 fi echo "$LAST_HOUR_LOG" | "$CLAUDE_BIN" -p " 다음은 지난 1시간의 애플리케이션 로그다. 다음 항목을 분석해서 이상 여부를 JSON으로 반환해줘: - error_count: ERROR 레벨 로그 건수 - critical_errors: CRITICAL/FATAL 에러 목록 (최대 5개) - anomaly_detected: 이상 패턴 감지 여부 (true/false) - summary: 한 줄 요약 " \ --output-format json | jq -r '.result' > "$ALERT_FILE" # 이상 감지 시 슬랙 알림 (선택사항 — 웹훅 URL 설정 후 사용) # ANOMALY=$(jq -r '.anomaly_detected' "$ALERT_FILE") # if [ "$ANOMALY" = "true" ]; then # curl -s -X POST "$SLACK_WEBHOOK" -d "{\"text\": \"이상 감지: $(jq -r '.summary' $ALERT_FILE)\"}" # fi echo "[$(date)] 로그 분석 완료"
예시 3: PR이 올라오면 자동 리뷰 (GitHub Actions + Claude Code)
GitHub Actions에서 Claude Code를 실행해 PR이 생성될 때마다 자동으로 코드 리뷰 코멘트를 추가하는 워크플로우다. 공식 문서 기준으로 anthropics/claude-code-action을 사용한다.
.github/workflows/claude-review.ymlname: Claude Code Review on: pull_request: types: [opened, synchronize] jobs: review: runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Claude Code Review uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | 이 PR의 변경사항을 코드 리뷰해줘. 다음 기준으로 평가하고 GitHub PR 코멘트 형식으로 작성해줘: 1. 버그 가능성 (심각도: HIGH / MEDIUM / LOW) 2. 성능 문제 3. 보안 취약점 4. 코드 스타일 위반 긍정적인 부분도 함께 언급해줘. allowed_tools: "Read,Bash"
ANTHROPIC_API_KEY는 GitHub 리포지토리의 Settings → Secrets and variables → Actions에서 등록해야 한다. 워크플로우 파일에 직접 키를 넣으면 절대 안 된다. anthropics/claude-code-action의 최신 버전은 github.com/anthropics/claude-code-action에서 확인할 것.launchd (macOS) / systemd timer (Linux) 대안
cron이 간단하고 범용적이지만, 더 세밀한 제어가 필요하다면 OS 네이티브 스케줄러를 사용하는 것이 낫다.
macOS: launchd
macOS에서는 launchctl과 plist 파일로 작업을 등록한다. cron보다 복잡하지만 네트워크 상태 감지, 로그 자동 관리, 실패 시 재시도 등이 내장되어 있다.
~/Library/LaunchAgents/com.myname.claude-daily.plist<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.myname.claude-daily</string> <key>ProgramArguments</key> <array> <string>/bin/bash</string> <string>/Users/username/scripts/daily-code-report.sh</string> </array> <!-- 매일 새벽 2시 실행 --> <key>StartCalendarInterval</key> <dict> <key>Hour</key> <integer>2</integer> <key>Minute</key> <integer>0</integer> </dict> <key>StandardOutPath</key> <string>/var/log/claude-launchd.log</string> <key>StandardErrorPath</key> <string>/var/log/claude-launchd-error.log</string> </dict> </plist>
launchd 등록 및 관리 명령어# plist 등록 (로드) launchctl load ~/Library/LaunchAgents/com.myname.claude-daily.plist # 즉시 수동 실행 (테스트용) launchctl start com.myname.claude-daily # 등록 해제 launchctl unload ~/Library/LaunchAgents/com.myname.claude-daily.plist # 등록된 작업 목록 확인 launchctl list | grep myname
Linux: systemd timer
systemd 기반 Linux(Ubuntu, Debian, Fedora 등)에서는 .service와 .timer 유닛 파일로 스케줄을 구성한다. cron보다 의존성 관리가 명확하고 journalctl로 로그를 통합 관리할 수 있다.
~/.config/systemd/user/claude-daily.service + .timer# --- claude-daily.service --- [Unit] Description=Claude Code 일일 코드 품질 리포트 [Service] Type=oneshot ExecStart=/bin/bash /home/username/scripts/daily-code-report.sh StandardOutput=journal StandardError=journal --- # --- claude-daily.timer --- [Unit] Description=Claude Code 일일 실행 타이머 [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true [Install] WantedBy=timers.target --- # 등록 및 활성화 systemctl --user daemon-reload systemctl --user enable --now claude-daily.timer # 상태 확인 systemctl --user status claude-daily.timer # 로그 확인 journalctl --user -u claude-daily.service -f
/loop 명령어와 cron 자동화의 차이
Claude Code의 /loop 명령어와 cron 자동화는 비슷해 보이지만 근본적으로 다른 방식이다.
| 항목 | /loop (대화형) | cron + claude -p (비대화형) |
|---|---|---|
| 실행 환경 | 터미널 세션 안에서 동작 | 터미널이 닫혀 있어도 실행 |
| 컨텍스트 유지 | 이전 대화 컨텍스트 유지됨 | 매 실행마다 새 컨텍스트 |
| 중단 조건 | 사용자가 직접 중단 | 스크립트 종료 시 자동 종료 |
| 스케줄링 | 수동 실행 필요 | OS 수준에서 자동 실행 |
| 적합한 사용 | 긴 작업을 반복적으로 진행할 때 | 정기적인 배치 작업 |
| 로그 관리 | 터미널 출력만 | 파일로 영구 저장 가능 |
실용적인 기준: 지금 이 작업을 완료하기 위해 컴퓨터 앞에 앉아 있어야 한다면 /loop, 매일 새벽 3시에 내가 자고 있을 때 실행돼야 한다면 cron이다.
--remote 플래그로 클라우드에서 실행하기
로컬 머신의 전원을 꺼도 작업을 계속 실행하고 싶다면 --remote 플래그를 사용한다. 2026년 3월 기준 Claude Code의 원격 실행 기능은 Anthropic 클라우드 환경에서 실행되며, 로컬 파일 시스템 접근은 별도 설정이 필요하다.
--remote 플래그 기본 사용# 원격 환경에서 헤드리스 실행 claude --remote -p "리포지토리를 클론하고 테스트를 실행한 결과를 알려줘" # 원격 실행 + 결과 저장 claude --remote -p "분석 작업" --output-format json > remote-result.json # 원격 실행 시 GitHub 리포지토리 컨텍스트 설정 claude --remote -p "https://github.com/username/repo의 최신 커밋을 분석해줘"
--remote는 로컬 파일 시스템에 직접 접근할 수 없다. 원격 실행에서 코드베이스를 분석하려면 GitHub URL이나 공개 접근 가능한 리포지토리가 필요하다. 로컬 파일을 다루는 배치 작업은 로컬 cron + claude -p 조합이 여전히 더 실용적이다. 원격 실행 기능의 최신 상태는 공식 문서에서 확인할 것.1. 절대경로만 사용: 스크립트 안의 모든 경로를 절대경로로 작성한다. cron의
$HOME은 예상과 다를 수 있다.2. 로그는 항상 남긴다:
>> logfile 2>&1 패턴을 모든 cron 작업에 붙인다. 문제 발생 시 로그 없이 디버깅은 거의 불가능하다.3. 스크립트를 먼저 수동으로 테스트한다: cron에 등록하기 전에 터미널에서 직접 실행해서 에러가 없는지 확인한다.