「日次バックアップを毎晩自動で実行したい」「定期バッチを設定したいけれど、crontabの5つのフィールドの並び順をいつも忘れてしまう」――Linuxサーバーを運用・自動化するエンジニアなら、誰もが一度は通る道です。
cron(およびその設定を行う crontab)は、Linux環境における定時実行の標準ツールです。基本構文さえ押さえれば、分単位・時間単位・曜日指定・毎月実行などあらゆるスケジュールを柔軟に自動化できます。しかし一方で、「手動実行だと正常に動くのに、なぜかcronに登録すると失敗する」という特有の落とし穴も数多く存在します。
そこで本記事では、crontabの最短基本構文から、実務で即コピペできる時間・曜日・実行間隔の早見表、flockによる二重起動防止などの実践テクニック、そして動かないときの4大原因とデバッグ法まで徹底解説します。「手作業は負け、スクリプトはシンプルに」を合言葉に、堅牢な自動化環境を構築しましょう。
1. 最短で動かす基本構文(5つのフィールド)
crontabは、設定ファイルに「いつ実行するか(日時)」と「何を実行するか(コマンド)」を1行ずつ記述します。日時指定は左から順に5つのフィールドで構成されており、半角スペースで区切って指定します。
# ┌───────────── 分 (0 - 59)
# │ ┌───────────── 時 (0 - 23)
# │ │ ┌───────────── 日 (1 - 31)
# │ │ │ ┌───────────── 月 (1 - 12)
# │ │ │ │ ┌───────────── 曜日 (0 - 7) ※0と7は日曜日、1:月, 2:火, 3:水, 4:木, 5:金, 6:土
# │ │ │ │ │
# * * * * * [実行するコマンド]
指定に使える4つの特殊記号
各フィールドには数値だけでなく、以下の特殊記号を組み合わせて柔軟なスケジュールを指定できます。
| 記号 | 意味 | 記述例 | 動作解説 |
|---|---|---|---|
* |
すべて(毎〜) | * * * * * |
毎分・毎時・毎日・毎月・毎曜日(毎分実行) |
, |
複数指定(カンマ区切り) | 0 9,18 * * * |
毎日 9:00 と 18:00 の2回実行 |
- |
範囲指定(ハイフン) | 0 9-18 * * * |
9:00から18:00まで毎時0分に実行(9, 10, 11…18時) |
/ |
ステップ(間隔指定) | */10 * * * * |
10分ごとに実行(0, 10, 20, 30, 40, 50分) |
crontabの編集と確認コマンド
cronジョブの登録・編集・確認は、専用の crontab コマンドで行います。
# 現在のログインユーザーのcrontabを編集(vi等のエディタが起動)
crontab -e
# 現在登録されているcrontabの一覧を表示
crontab -l
# 他の特定ユーザーのcrontabを表示・編集(root権限が必要)
sudo crontab -u nginx -l
sudo crontab -u nginx -e
【注意】
crontab -rの誤爆に注意!
crontab -rを実行すると、確認ダイアログなしで現在登録されているすべてのcron設定が完全削除されます。キーボード上でeとrが隣り合っているため、実務では編集前にcrontab -l > crontab.bakでバックアップを取る習慣をつけておくと安全です。
2. crontab 時間・間隔指定早見表
実務で頻出する定期実行パターンの構文早見表です。該当する行をそのままコピーして利用できます。
| 実行タイミング | 設定例(5フィールド) | コマンド記述例 |
|---|---|---|
| 毎日 深夜3:00 | 0 3 * * * |
/usr/local/bin/backup.sh |
| 毎時 0分(1時間ごと) | 0 * * * * |
/usr/local/bin/healthcheck.sh |
| 10分ごと | */10 * * * * |
/usr/local/bin/sync_data.sh |
| 5分ごと | */5 * * * * |
/usr/local/bin/queue_worker.sh |
| 30分ごと(毎時0分と30分) | 0,30 * * * * |
/usr/local/bin/cache_clear.sh |
| 毎週月曜 朝9:00 | 0 9 * * 1 |
/usr/local/bin/weekly_report.sh |
| 平日(月〜金)9:00〜18:00の毎時 | 0 9-18 * * 1-5 |
/usr/local/bin/business_monitor.sh |
| 土日(週末)深夜2:00 | 0 2 * * 0,6 |
/usr/local/bin/weekend_maintenance.sh |
| 毎月1日 深夜0:00 | 0 0 1 * * |
/usr/local/bin/monthly_batch.sh |
| 毎月15日と月末(30日)23:00 | 0 23 15,30 * * |
/usr/local/bin/billing_calc.sh |
| 3時間ごと(0:00, 3:00, 6:00…) | 0 */3 * * * |
/usr/local/bin/cleanup_tmp.sh |
3. 実務で役立つ設定テクニック(コピペ実例)
3.1 ログ出力の管理(標準出力と標準エラー出力をファイルに記録)
cronで実行されたスクリプトの出力(標準出力・標準エラー出力)は、デフォルトではOSのローカルメール(mailx)に送られるか破棄されます。トラブルシューティングを迅速に行うため、必ずログファイルへリダイレクトしましょう。
# 標準出力(1)と標準エラー出力(2)を同じログファイルに追記(>>)して保存
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# 標準出力とエラー出力を別々のファイルに分けて保存
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>> /var/log/backup_err.log
# 出力を一切保存しない場合(破棄)
*/5 * * * * /usr/local/bin/ping_check.sh > /dev/null 2>&1
詳しいリダイレクトの仕組みや順序のルールについては、標準エラー出力のリダイレクト完全ガイド(2>&1の仕組み)も併せて参考にしてください。
3.2 特殊なキーワード指定(@reboot, @daily, @hourly)
数字の5フィールドの代わりに、@ から始まる短縮キーワード(エイリアス)を使用することも可能です。可読性が向上し、設定ミスを防げます。
| エイリアス | 相当する設定 | 実行タイミング |
|---|---|---|
@reboot |
起動時のみ | OS起動時(再起動後)に1度だけ自動実行 |
@hourly |
0 * * * * |
毎時0分(1時間に1回) |
@daily / @midnight |
0 0 * * * |
毎日深夜0:00(1日に1回) |
@weekly |
0 0 * * 0 |
毎週日曜深夜0:00(週に1回) |
@monthly |
0 0 1 * * |
毎月1日深夜0:00(月に1回) |
@yearly / @annually |
0 0 1 1 * |
毎年1月1日深夜0:00(年に1回) |
# サーバー起動時に自動で常駐スクリプトを立ち上げる実例
@reboot /usr/local/bin/start_tunnel.sh >> /var/log/boot_tunnel.log 2>&1
# 毎日深夜に日次レポートを生成する実例
@daily /usr/local/bin/daily_summary.sh >> /var/log/daily_summary.log 2>&1
3.3 複数コマンドの順次実行(&& や ; の活用)
1つのスケジュールで連続した複数の処理を行いたい場合は、演算子でコマンドを連結します。
# && : 前の処理が「成功(終了ステータス0)」した場合のみ次の処理を実行
0 4 * * * /usr/bin/mysqldump -u root mydb > /tmp/db.sql && /usr/local/bin/aws s3 cp /tmp/db.sql s3://my-backup-bucket/
# ; : 前の成否に関わらず順次実行
0 5 * * * /usr/local/bin/task_a.sh ; /usr/local/bin/task_b.sh
3.4 flockを使った多重起動防止(前回の処理が終わっていない場合の対策)
バッチ処理のデータ量が増加して実行時間が予定間隔(例: 10分)を超えてしまうと、前回の処理が終わる前に次のcronプロセスが走り、二重処理やCPU・メモリ枯渇の原因になります。
これを確実に防ぐのが flock コマンドによるファイル排他制御です。
# -n (non-blocking): 前回のプロセスがロック中の場合、待機せず即座にスキップして終了
*/10 * * * * /usr/bin/flock -n /var/lock/heavy_sync.lock /usr/local/bin/heavy_sync.sh >> /var/log/heavy_sync.log 2>&1
多重起動防止やロック制御の設計パターンについては、ロックと並列安全(flock・PID排他制御)で詳しく解説しています。
4. 「手動では動くのにcronだと動かない」4大原因とデバッグ法
「ターミナルから bash script.sh を手動で叩くと正常に動くのに、cronに登録すると全く動かない・失敗する」という現象は、Linux環境の自動化で最も遭遇するトラブルです。原因の9割は以下の4つに集約されます。
原因1: PATH環境変数の違い(コマンドが見つからない)
【症状】 command not found や exit code 127 で処理が失敗する。
【原因】 ログインシェルと異なり、cronの実行環境には /usr/bin:/bin などの最小限の PATH しか定義されていません。/usr/local/bin、~/.local/bin、Node.js、Pythonなどのパスが通っていません。
【解決策】 コマンドおよび実行ファイルは必ず「絶対パス」で記述するか、crontabの先頭で PATH を明示的に定義します。
# 解決策A: crontabの冒頭でPATHを宣言しておく(推奨)
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SHELL=/bin/bash
# 解決策B: 実行コマンドをすべて絶対パス(whichコマンドで確認したパス)にする
0 3 * * * /usr/local/bin/python3 /opt/scripts/export_data.py
原因2: 作業ディレクトリ(CWD)の違い(相対パスが狂う)
【症状】 No such file or directory エラーになる、またはホームディレクトリ直下に意図しないファイルが出力される。
【原因】 cronジョブはデフォルトで実行ユーザーのホームディレクトリ($HOME)を作業ディレクトリとして起動します。スクリプト内で ./config.ini や data/output.csv などの相対パスを使っていると、参照先がずれて失敗します。
【解決策】 シェルスクリプトの冒頭で、「スクリプト自身の配置ディレクトリ」へカレントディレクトリを移動する定型コードを記述します。
#!/usr/bin/env bash
set -euo pipefail
# スクリプトが置かれているディレクトリへ確実に移動
cd "$(dirname "$0")"
# ここから先は相対パスで安全にファイルを読み書き可能
./process_data.sh config.ini >> output.log
原因3: ユーザー環境変数(.bashrc / .profile)が読まれない
【症状】 必要な環境変数($DATABASE_URL, $AWS_PROFILE, $NODE_ENV 等)が空になりエラーになる。
【原因】 cronは「非対話型・非ログインシェル(non-interactive, non-login shell)」として動作するため、ログイン時に自動読み込みされる ~/.bashrc や ~/.profile がロードされません。
【解決策】 cronコマンド行、またはスクリプト冒頭で明示的に設定ファイルを source(または .)します。
# cron行の先頭で.bashrcを明示的に読み込んでから実行
0 6 * * * . $HOME/.bashrc; /usr/local/bin/daily_task.sh >> /var/log/daily_task.log 2>&1
原因4: 標準エラー出力の確認不足(サイレントエラー)
【症状】 スクリプトが途中で終了しているのに、エラー理由が一切わからない。
【原因】 リダイレクトを指定していないか、標準出力(1)のみをリダイレクトしていて標準エラー出力(2)を取りこぼしている。
【解決策】 エラー出力をログファイルへ合流(2>&1)させるか、エラー専用のログファイルを用意して出力を捕捉します。
# エラー専用ログに分けて詳細をキャッチする設定例
0 2 * * * /usr/local/bin/job.sh 1>> /var/log/job.log 2>> /var/log/job_error.log
5. まとめ & 関連記事
Linux環境での定期実行・自動化を支える crontab の重要ポイントをおさらいしましょう。
- 5つのフィールド順をマスター: 「分・時・日・月・曜日」の順番とステップ指定(
*/N)を活用して柔軟なスケジュールを組む。 - 安全な運用設計: バッチの多重起動には
flock -n、ログ確認には>> log 2>&1のリダイレクトをセットで導入する。 - 動かない時の3大鉄則: 「絶対パス指定」「
cd "$(dirname "$0")"によるディレクトリ固定」「環境変数の明示的読み込み」を徹底する。
自動化スクリプトの作成やエラー処理をさらに深掘りしたい方は、以下の関連記事もぜひチェックしてみてください。

コメント