Claude Code を cron / systemd で定期実行する(-p 非対話モード)
Claude Code は対話で使うだけでなく、-p(print)モードで「指示を渡して結果だけ受け取る」使い方ができます。これを cron や systemd timer から呼べば、VPS 上で定期的に作業させられます。
前提として、VPS に Claude Code が入っている状態から始めます。まだの場合は ConoHa VPS に Claude Code を入れる手順 を先に。
-p モードの基本
cd ~/work/myrepo
claude -p "テストを実行して、失敗があれば原因を調べて修正し、変更内容を要約して"
標準出力に結果が返ります。JSON で受け取りたい場合は出力形式を指定します。
claude -p "..." --output-format json
オプション名はバージョンで変わることがあるため、claude --help で確認してください。
認証は API キーにする
cron からはブラウザ認証ができません。API キーを環境変数で渡します。
# ~/.claude_env(パーミッション 600)
export ANTHROPIC_API_KEY=sk-ant-...
API は従量課金です。1 回のジョブで何トークン使うかを、まず手動で数回動かして把握してから定期実行にします。
許可するツールを絞る
非対話モードでは、人が「許可」を押せません。何を許可するかを明示します。
claude -p "テストを実行して結果を要約して" \
--allowedTools "Read,Bash(npm test)" \
--max-turns 10
- 読み取りとテスト実行だけ:
Read,Bash(npm test) - 修正もさせる:
Read,Edit,Write,Bash(npm test),Bash(git diff) git pushやrmは許可しない。人がレビューしてから push する
--max-turns で暴走を止められます。
ジョブスクリプトにする
#!/usr/bin/env bash
# ~/bin/nightly-test.sh
set -euo pipefail
source ~/.claude_env
export PATH="$HOME/.local/bin:$PATH"
cd ~/work/myrepo
git pull --ff-only
LOG=~/logs/nightly-$(date +%F).log
mkdir -p ~/logs
claude -p "npm test を実行して、失敗があれば原因を調べて修正して。修正した場合は git diff を出力して。" \
--allowedTools "Read,Edit,Write,Bash(npm test),Bash(git diff)" \
--max-turns 15 \
> "$LOG" 2>&1
# 変更があればブランチに退避(push は人が確認してから)
if ! git diff --quiet; then
git checkout -b "auto/nightly-$(date +%F)"
git commit -am "auto: nightly fix"
git checkout -
fi
chmod +x ~/bin/nightly-test.sh
cron で毎晩 3 時に動かす
crontab -e
0 3 * * * /home/dev/bin/nightly-test.sh
cron は PATH が最小限なので、スクリプト内で環境変数と PATH を設定しておきます(上のスクリプトはそうしています)。
systemd timer で動かす(ログ管理が楽)
~/.config/systemd/user/nightly-test.service
[Unit]
Description=Claude Code nightly test
[Service]
Type=oneshot
EnvironmentFile=%h/.claude_env
ExecStart=%h/bin/nightly-test.sh
~/.config/systemd/user/nightly-test.timer
[Unit]
Description=Run nightly test at 03:00
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
systemctl --user daemon-reload
systemctl --user enable --now nightly-test.timer
systemctl --user list-timers
journalctl --user -u nightly-test.service -n 50
ログアウト後も動かすには loginctl enable-linger dev を一度実行します。
結果を通知する
ログの末尾を Discord の Webhook に投げると、朝に結果が見られます。
tail -c 1500 "$LOG" > /tmp/nightly-tail.txt
python3 - <<'PY'
import json, os, urllib.request
body = open('/tmp/nightly-tail.txt', encoding='utf-8', errors='replace').read()
req = urllib.request.Request(
os.environ['DISCORD_WEBHOOK_URL'],
data=json.dumps({'content': 'nightly-test 完了\n' + body}).encode(),
headers={'Content-Type': 'application/json'},
)
urllib.request.urlopen(req)
PY
実際に動かしている例
(執筆中)
まとめ
-pモードで指示を渡し、結果だけ受け取れる- 定期実行は API キー認証。使用量を先に把握する
- 許可ツールと
--max-turnsで暴走を防ぐ。push は人がやる - cron でも動くが、ログを見るなら systemd timer が楽
- VPS の選び方は Claude Code を VPS で 24 時間動かす構成と費用 へ
よくある質問
Q. cron から Claude Code を動かすとログインを求められませんか?
ANTHROPIC_API_KEY を環境変数に置いておけば、ブラウザ認証なしで動きます。定期実行は API キー認証にしてください。
Q. 勝手に危険なコマンドを実行しませんか?
非対話モードでは許可するツールを明示的に指定します。読み取りとテスト実行だけ許可する、といった絞り込みができます。
検証環境: Ubuntu 24.04 LTS / ConoHa VPS 2GB / 2026-09-19 時点。料金や仕様は変更されることがあるため、最新情報は公式サイトで確認してください。