카테고리 없음

Claude Code 설치(클로드코드 설치)부터 첫 자동화까지: 리눅스에서 매일 도는 작업 만들기

코드짜는아빠 2026. 9. 30. 09:46

새벽 1시에 혼자 도는 Claude

제 리눅스 노트북에서는 매일 새벽 1시에 Claude Code가 한 번 돕니다. Claude Code 본체와 플러그인, 같이 쓰는 코딩 도구에 새 버전이 나왔는지 확인하고, 바꿀 만한 게 있으면 제안만 남기는 작업입니다. 직접 고치지는 않습니다. 이 노트북에 걸어 둔 systemd 타이머가 지금(2026-09-30) 25개인데, 그중 하나입니다.

지난 글은 역할별 스킬을 만드는 이야기였습니다. 이번에는 Claude Code를 사람이 없을 때도 돌게 만드는 과정을 순서대로 적습니다. 설치하고, 대화창 없이 부르고, 타이머에 겁니다.

1. Claude Code 설치 방법: 리눅스 설치 명령어 (2026-09-30 공식 문서 기준)

공식 문서가 권하는 방법은 설치 스크립트 한 줄입니다.

curl -fsSL https://claude.ai/install.sh | bash

새 터미널을 열고 확인합니다.

claude --version   # 예: 2.1.285 (Claude Code)
claude doctor      # 설치 상태와 설정 파일 오류를 읽기 전용으로 점검

그다음 claude 를 한 번 실행하면 브라우저가 열립니다. 거기서 로그인하면 됩니다. 무료 요금제에는 Claude Code가 들어 있지 않고, Pro · Max · Team · Enterprise 또는 Console(API) 계정이 필요합니다.

리눅스 기준 요구 사항은 Ubuntu 20.04 이상 또는 Debian 10 이상, 메모리 4GB 이상입니다. apt · dnf 저장소나 npm으로 설치할 수도 있습니다. 다만 공식 설치 스크립트로 깔아야 백그라운드 자동 업데이트가 됩니다. 스크립트는 실행 파일을 ~/.local/bin/claude 에 둡니다. 이 경로는 3단계에서 다시 나옵니다.

2. 대화 없이 부르기: claude -p

-p(--print)를 붙이면 대화창을 열지 않고 답만 출력한 뒤 끝납니다. 입력은 파이프로 넘길 수 있습니다.

git log --since=yesterday --oneline \
  | claude -p "어제 커밋 목록이다. 무엇을 했는지 세 줄로 요약해 줘." \
      --model sonnet --tools "" --output-format json --max-budget-usd 1

새벽 1시 작업에도 아래 옵션이 모두 들어 있습니다.

옵션 하는 일 넣은 이유
--tools "" 내장 도구(파일 읽기·수정, 셸 실행)를 전부 끔 답만 받으면 되는 작업입니다. 사람 없이 도는 동안 파일을 건드릴 일 자체를 없앴습니다
--output-format json 결과를 JSON으로 받음 스크립트가 성공 여부(is_error)와 사용량을 읽어야 합니다
--max-budget-usd 쓴 금액이 이 값에 닿으면 멈춤 폭주 방지. 새벽 1시 작업은 5달러로 잡았습니다
--model 모델 지정 요약 정도는 작은 모델로 충분합니다

하나 조심할 점. --tools "" 는 내장 도구만 끕니다. 연결해 둔 MCP 도구는 그대로 남습니다.

직접 재 본 것: 같은 요약, 27만 토큰과 4천 토큰

이 글을 쓰면서 위 명령을 조건만 바꿔 가며 돌려 봤습니다. 넣은 것도 매번 같은 어제 커밋 목록입니다.

조건 입력 토큰 결과
프로젝트 폴더에서 실행, 모델 지정 안 함(제 기본 설정은 Opus) 272,792 상한 1달러에 걸려 실패
같은 폴더, --model sonnet 272,571 역시 상한에 걸려 실패
빈 폴더에서 실행 139,777 성공
+ --strict-mcp-config (MCP 서버를 안 불러옴) 13,574 성공
+ --disable-slash-commands --setting-sources project 4,331 성공

세 줄 요약에 27만 토큰. 그 대부분은 질문과 함께 딸려 들어간 설정이었습니다. -p 로 불러도 Claude Code는 평소처럼 CLAUDE.md, 전역 규칙, 스킬 목록, 연결해 둔 MCP 서버의 도구 설명까지 전부 읽고 시작합니다. 저처럼 규칙과 MCP 연결을 많이 쌓아 둘수록 딸려 가는 양도 커집니다. 모델을 작은 걸로 바꿔도 입력 토큰은 거의 그대로였습니다.

그래서 자동 작업에는 세 가지를 지킵니다.

  1. 작업 전용 빈 폴더에서 실행합니다. 프로젝트 폴더의 CLAUDE.md가 따라오지 않습니다.
  2. 필요 없는 MCP 서버를 안 부릅니다(--strict-mcp-config).
  3. 스킬과 사용자 전역 설정을 끕니다(--disable-slash-commands --setting-sources project).

--bare 라는 최소 모드도 있습니다. 써 보니 「Not logged in」 으로 끝났습니다. claude --help 를 보면 --bare 는 구독 로그인 정보를 읽지 않고 API 키로만 인증하거든요. 구독 계정이라면 위 세 가지로 줄이는 편이 낫습니다.

상한은 이번에 제값을 했습니다. 첫 실행이 1달러에서 멈췄으니까요. 설정을 줄이지 않고 그대로 타이머에 걸었다면 매일 아침 이만한 호출이 한 번씩 나갔을 겁니다. 구독 요금제에서는 이 금액이 실제 청구액이 아니라 사용량을 달러로 환산한 값입니다. 그래도 그만큼 한도는 줄어듭니다.

3. systemd 사용자 타이머로 매일 돌리기

cron도 되지만 저는 systemd 사용자 타이머를 씁니다. 실행 기록이 journalctl 에 남고, 컴퓨터가 꺼져 있어 놓친 실행을 나중에 따라잡게 할 수 있어서입니다.

스크립트 ~/bin/daily-note.sh:

#!/usr/bin/env bash
set -euo pipefail
cd "$HOME/daily-note"   # 설정이 따라오지 않는 작업 전용 폴더
git -C "$HOME/my-project" log --since=yesterday --oneline \
  | claude -p "어제 커밋 목록이다. 무엇을 했는지 세 줄로 요약해 줘." \
      --model sonnet --tools "" --output-format json --max-budget-usd 1 \
      --strict-mcp-config --disable-slash-commands --setting-sources project \
  > "$HOME/daily-note/$(date +%F).json"

서비스 ~/.config/systemd/user/daily-note.service:

[Unit]
Description=Daily commit summary by Claude Code

[Service]
Type=oneshot
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=%h/bin/daily-note.sh

타이머 ~/.config/systemd/user/daily-note.timer:

[Unit]
Description=Run daily-note every morning at 07:00

[Timer]
OnCalendar=*-*-* 07:00:00
Persistent=true

[Install]
WantedBy=timers.target

켜는 명령입니다.

systemctl --user daemon-reload
systemctl --user enable --now daily-note.timer
loginctl enable-linger "$USER"   # 로그인하지 않은 상태에서도 사용자 타이머가 돌게

Persistent=true 가 앞에서 말한 그 따라잡기 설정입니다. enable-linger 를 빼먹으면 로그아웃해 있는 동안 타이머가 돌지 않습니다.

조용히 죽는 함정: status=127

서비스 파일에 Environment=PATH=… 줄을 넣은 이유가 있습니다. systemd 사용자 서비스는 제 터미널의 PATH를 물려받지 않거든요. 이 줄이 없으면 ~/.local/bin 에 있는 claude 를 못 찾습니다. 이 글을 쓰면서 PATH를 /usr/bin:/bin 으로만 두고 위 스크립트를 돌려 보니 바로 이렇게 끝났습니다.

line 5: claude: command not found
exit=127

실제 운영에서 이미 겪은 일입니다. 매일 아침 저장소 상태를 보는 자체 점검 서비스가 이틀 연속(8월 31일, 9월 1일) status=127 로 죽어 있었습니다. 원인은 같았습니다. nvm으로 깐 node를 /usr/bin/env node 로 불렀는데, systemd의 PATH에는 node가 없었습니다. 알림도 없었습니다. 당시 이 서비스는 텔레그램으로 알림을 보내지 않는 설정이었고, 실패는 journalctl 에만 남았습니다. 그걸 매일 읽는 사람은 없었습니다.

그 뒤로 지키는 규칙은 두 가지입니다.

  • 서비스 파일에서는 실행 파일을 절대 경로로 쓰거나, Environment=PATH= 로 경로를 직접 적습니다.
  • enable 한 뒤에도 한 번은 직접 돌려서 종료 상태를 봅니다.
systemctl --user start daily-note.service
systemctl --user status daily-note.service   # Main PID 줄의 status=0/SUCCESS 확인
journalctl --user -u daily-note.service -n 20

처음 만든다면

매일 손으로 하던 확인 작업 하나로 시작하세요. 어제 커밋 요약, 에러 로그 훑기, 의존성 업데이트 확인 정도면 됩니다. 도구는 끄고(--tools ""), 상한을 걸고(--max-budget-usd), 빈 폴더에서 돌리고, 첫 실행은 직접 해서 결과 파일과 종료 상태를 확인하세요.


다음 글에서는 매일 돌리다 보면 부딪히는 요금제 한도 이야기를 합니다. 한도에 실제로 걸려 작업이 멈춘 날의 기록입니다.

이 블로그에 쓴 글들을 바탕으로 전자책과 템플릿 묶음을 만들어 볼까 고민하고 있어요. 낼지, 낸다면 언제일지는 아직 미정.

나오면 알림을 받고 싶은 분은 제목을 [출시 알림]으로 해서 codenara.contact@gmail.com 으로 메일 주세요.

개인정보 안내: 받은 메일 주소는 출시 알림 한 번 보내는 데만 쓰고, 보내고 나면 지워요. 내지 않기로 하면 그때 지우고, 요청하시면 그 전에라도 바로 지웁니다.

이런 자동화를 직접 세팅하고 싶거나 팀 환경에 맞게 설계해 보고 싶다면 codenara.contact@gmail.com 으로 연락 주세요. 교육·세팅 문의는 따로 받고 있습니다.