Cron とは?——歴史から紐解く
Cron は Unix の世界で最も古く、最も長く使われ続けているユーティリティの一つです。1979 年、Ken Thompson が Unix V7(第 7 版 Unix)の一部としてベル研究所で開発しました。"cron" という名前はギリシャ語の chronos(χρόνος)、すなわち「時間」に由来します。
オリジナルの cron デーモンは毎分起動し、タスクリストをスキャンして、時刻が一致したコマンドを実行するという、極めてシンプルな設計でした。「時刻表現 + コマンド」というこのアーキテクチャは、40 年以上経った今も本質的に変わっていません。現代の Linux ディストリビューションは Vixie Cron(Paul Vixie, 1988)や cronie などの改良版を採用し、macOS は launchd を使っています。Cron の影響はアプリケーション層にも及び、Java の Quartz Scheduler、Python の APScheduler、Node.js の node-cron、そして AWS EventBridge や Google Cloud Scheduler などのクラウドサービスも cron 式の構文を踏襲しています。
標準 5 フィールド Cron 構文
標準的な cron 式はスペース区切りの 5 つのフィールドで構成されます。
┌───────── 分 (0–59)
│ ┌─────── 時 (0–23)
│ │ ┌───── 日 (1–31)
│ │ │ ┌─── 月 (1–12 または JAN–DEC)
│ │ │ │ ┌─ 曜日 (0–7、0 と 7 は両方日曜、または SUN–SAT)
│ │ │ │ │
* * * * * コマンド
各フィールドの詳細
| フィールド | 使用可能な値 | 説明 |
|---|---|---|
| 分 | 0–59 | 何分に実行するか |
| 時 | 0–23 | 何時に実行するか(24 時間制) |
| 日 | 1–31 | 月の何日に実行するか |
| 月 | 1–12 または JAN–DEC | 何月に実行するか |
| 曜日 | 0–7 または SUN–SAT | 何曜日に実行するか(0 と 7 は両方日曜) |
重要: 「日」と「曜日」を同時に * 以外で指定した場合、cron は OR ロジックで動作します。どちらかの条件が一致すればジョブが実行されます。これは初心者が誤解しやすいポイントです。
拡張 6 フィールド構文(秒付き)
Quartz Scheduler(Java)、Spring Framework の @Scheduled アノテーション、一部のクラウドプラットフォームでは、先頭に秒フィールドが追加されます。
┌─────────── 秒 (0–59)
│ ┌───────── 分 (0–59)
│ │ ┌─────── 時 (0–23)
│ │ │ ┌───── 日 (1–31)
│ │ │ │ ┌─── 月 (1–12)
│ │ │ │ │ ┌─ 曜日 (1–7、Quartz では 1=日曜)
│ │ │ │ │ │
0 * * * * ?
Quartz の曜日フィールドは Unix cron とは番号体系が異なります(1=日曜、7=土曜)。使用する際は注意が必要です。
特殊文字の解説
* — 任意の値
そのフィールドのすべての値にマッチします。* * * * * は毎分実行を意味します。
, — 値リスト
複数の個別値を指定します。0 9,12,18 * * * は毎日 9:00、12:00、18:00 に実行されます。
- — 範囲
連続した範囲を指定します。0 9-17 * * 1-5 は月曜〜金曜の 9 時〜17 時の毎時 0 分に実行されます。
/ — ステップ値
*/n は「n 単位ごと」を意味します。*/15 * * * * は 15 分ごとの実行です。範囲との組み合わせも可能で、10-50/10 は 10、20、30、40、50 を意味します。
? — 指定なし(Quartz/Spring のみ)
「日」または「曜日」フィールドで「どの値でもよい」を示します。両フィールドを同時に指定すると曖昧になるため、一方を ? にする必要があります。
L — 最後(Quartz/Spring のみ)
「日」フィールドでは月の最終日、「曜日」フィールドではその月の最後のその曜日を表します。0 0 L * ? は毎月最終日の深夜 0 時に実行されます。
W — 最近の平日(Quartz/Spring のみ)
15W は 15 日に最も近い平日を意味します。15 日が土曜なら 14 日(金曜)、日曜なら 16 日(月曜)に実行されます。
# — 第 N 曜日(Quartz/Spring のみ)
2#3 は「その月の第 3 火曜日」を意味します。書式は <曜日>#<何番目> です。0 10 ? * 2#1 は毎月第 1 月曜日の 10:00 に実行されます。
特殊エイリアス
ほとんどの cron 実装は以下の便利なエイリアスをサポートしています。
| エイリアス | 等価表現 | 説明 |
|---|---|---|
@yearly |
0 0 1 1 * |
毎年 1 月 1 日の深夜 |
@annually |
0 0 1 1 * |
@yearly と同じ |
@monthly |
0 0 1 * * |
毎月 1 日の深夜 |
@weekly |
0 0 * * 0 |
毎週日曜の深夜 |
@daily |
0 0 * * * |
毎日深夜 |
@midnight |
0 0 * * * |
@daily と同じ |
@hourly |
0 * * * * |
毎時 0 分 |
@reboot |
— | システム起動時に 1 回実行 |
よく使う Cron 式一覧
| 式 | 意味 |
|---|---|
* * * * * |
毎分 |
0 * * * * |
毎時 0 分 |
*/15 * * * * |
15 分ごと |
0 0 * * * |
毎日深夜 0 時 |
30 2 * * * |
毎日午前 2:30 |
0 9-17 * * 1-5 |
平日 9 時〜17 時の毎時 |
0 0 * * 0 |
毎週日曜の深夜 |
0 0 1 * * |
毎月 1 日の深夜 |
0 0 1 1 * |
毎年 1 月 1 日の深夜 |
0 6 * * 1-5 |
平日毎朝 6 時 |
0 */6 * * * |
6 時間ごと |
Linux での Crontab 操作
# 現在のユーザーの crontab を編集
crontab -e
# 現在の crontab を表示
crontab -l
# crontab を削除
crontab -r
# 別ユーザーの crontab を編集(root のみ)
crontab -u username -e
crontab の記述例
# 環境変数の設定
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
[email protected]
# 毎日午前 2:30 にバックアップ実行
30 2 * * * /usr/local/bin/backup.sh
# 毎週日曜の深夜にクリーンアップ(ログ付き)
0 0 * * 0 /usr/local/bin/cleanup.sh >> /var/log/cleanup.log 2>&1
# 15 分ごとにヘルスチェック
*/15 * * * * /usr/local/bin/health-check.sh
# タイムゾーンを指定して実行(GNU cron / cronie)
CRON_TZ=Asia/Tokyo
0 9 * * 1-5 /usr/local/bin/morning-report.sh
システム全体の Cron ディレクトリ
/etc/crontab— システム全体の crontab(各行にユーザー名フィールドが追加)/etc/cron.d/— パッケージやサービス用の個別 cron 設定ファイル/etc/cron.daily/、/etc/cron.hourly/、/etc/cron.weekly/、/etc/cron.monthly/—run-partsによって自動実行されるスクリプト置き場
macOS と Windows でのスケジューリング
macOS:launchd
macOS は launchd を推奨のスケジューリング機構として採用しており、.plist ファイルで定義します。ユーザータスクは ~/Library/LaunchAgents/、システムタスクは /Library/LaunchDaemons/ に置きます。ただし、cron も引き続き使用でき、多くの開発者がシンプルさから cron を好んでいます。
Windows:タスクスケジューラ
Windows には schtasks コマンドや GUI で操作するタスクスケジューラがあります。WSL(Windows Subsystem for Linux)を使えば Linux の cron 環境をそのまま利用できます。
アプリケーションレベルの Cron スケジューラ
Node.js — node-cron
const cron = require('node-cron');
// 毎日午前 2:30 に実行(タイムゾーン指定)
cron.schedule('30 2 * * *', async () => {
await runDailyBackup();
}, {
timezone: "Asia/Tokyo"
});
Python — APScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
scheduler = BlockingScheduler()
@scheduler.scheduled_job(CronTrigger.from_crontab('0 9 * * 1-5'))
def morning_job():
print("平日の朝 9 時になりました。")
scheduler.start()
Java — Quartz Scheduler
Quartz は秒を含む 6 フィールド式を使用し、L、W、#、? などの高度な文字もサポートします。
// 平日の午前 9:00 に実行
CronScheduleBuilder schedule = CronScheduleBuilder.cronSchedule("0 0 9 ? * MON-FRI");
クラウド・コンテナスケジューラ
AWS EventBridge Scheduler
6 フィールドの cron 式(UTC)を使用。「日」と「曜日」のどちらか一方を ? にする必要があります。
cron(0 2 * * ? *) # 毎日 UTC 午前 2 時
Google Cloud Scheduler
標準の Unix 5 フィールド cron 構文を使用し、タイムゾーンを指定できます。
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-image:latest
restartPolicy: OnFailure
concurrencyPolicy: Forbid を設定すると、前のジョブが完了していない場合に新しいジョブの起動を防止できます。
タイムゾーンの扱い
Cron はデフォルトでシステムタイムゾーン(サーバーでは多くの場合 UTC)で動作します。サーバーの UTC 設定を意識しないと、「午前 9 時に実行したいのに夜中に実行される」といった問題が起きます。
タイムゾーンに関するベストプラクティス:
- crontab の先頭に
CRON_TZ=Asia/Tokyoのように明示的に指定する - クラウドプラットフォームのタイムゾーン設定フィールドを活用する
- サマータイム(DST)の切り替え時に実行が重複したり欠落したりするリスクを避けるため、UTC での固定時刻を検討する
- cron 式のコメントに必ずタイムゾーンを記載する
セキュリティ上の注意点
Cron ジョブは高権限で実行されることが多く、攻撃の入り口になりやすいため、以下の点に注意してください。
最小権限の原則: タスクの実行に必要な最低限の権限を持つユーザーで実行し、root は避けてください。
認証情報のハードコーディング禁止: パスワードや API キーを crontab やスクリプトに直接書き込まないこと。権限を絞った環境変数ファイル(chmod 600)や AWS Secrets Manager などのシークレット管理サービスを使用してください。
スクリプトのパーミッション管理: cron スクリプトが他のユーザーから書き込み可能になっていないか確認してください。
chmod 750 /usr/local/bin/backup.sh
chown root:staff /usr/local/bin/backup.sh
監視とアラート: MAILTO= でエラーをメール受信し、Healthchecks.io や Cronitor などのデッドマンスイッチサービスでジョブが「実行されなかった」場合のアラートを設定してください。
ベストプラクティス
ジョブをべき等にする: 何度実行しても同じ結果になるよう設計する。障害からの回復が容易になります。
ファイルロックで多重実行を防ぐ: ジョブの実行時間がインターバルを超える可能性がある場合は flock を使用します。
*/5 * * * * flock -n /var/lock/myjob.lock /usr/local/bin/myjob.sh
出力を明示的にリダイレクトする:
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
デプロイ前に式を検証する: Cron Parser ツールで実際にいつ実行されるか確認してから本番に適用してください。
crontab をバージョン管理する: crontab ファイルを Git で管理し、Ansible や Puppet でデプロイすることで「設定のドリフト」を防ぎます。
よくある質問(FAQ)
Q:Cron ジョブが実行されないのはなぜですか?
よくある原因:①スクリプトに実行権限がない、②スクリプトがシェルの環境変数に依存しているが cron の環境は最小限、③パスの問題(cron は .bashrc を読まないので、コマンドは絶対パスで書く)、④cron デーモンが停止している(systemctl status cron で確認)。
Q:*/5 と 0/5 の違いは何ですか?
Unix cron では */5 は 0 から始まる 5 分刻み(0、5、10…55)を意味します。0/5 は Quartz や AWS EventBridge の書き方で、同じ意味です。
Q:毎秒実行することはできますか?
標準 cron の最小粒度は 1 分です。サブミニット単位のスケジューリングには、Quartz、APScheduler のインターバルトリガー、または systemd タイマー(OnCalendar=*:*:00/10)を使用してください。
Q:毎月末日に実行するにはどうすればよいですか?
標準 cron には「月末」の演算子がありません。「明日が 1 日かどうか」を判定する方法が一般的な代替策です。Quartz cron では日フィールドに L を使えます。
Q:0 0 * * 0 と @weekly の違いは何ですか?
完全に等価で、どちらも毎週日曜の深夜 0 時に実行されます。@weekly は多くのモダンな cron 実装が提供する助記エイリアスです。
Q:ターミナルでは動くのに cron で動かないスクリプトをデバッグするには?
Cron の実行環境は最小限(通常 HOME、LOGNAME、PATH=/usr/bin:/bin、SHELL=/bin/sh のみ)で、.bashrc や .profile は読み込まれません。スクリプトの先頭に #!/bin/bash と set -e を付け、絶対パスを使い、stdout/stderr をログファイルにリダイレクトしてください。
まとめ
Cron は 1979 年の誕生以来、Unix 自動化の要として機能し続け、クラウド時代においても進化を続けています。Linux サーバーの管理、Kubernetes ワークロードの調整、クラウドイベントトリガーの設定など、あらゆる場面で cron 式への深い理解がデバッグ時間の削減と本番障害の防止につながります。
重要ポイント:
- 5 フィールドの標準構文がほぼすべてのユースケースに対応
/はステップ、,はリスト、-は範囲を意味する- サーバーでは UTC を使うか、
CRON_TZで明示的に指定する - 最小権限・認証情報の非ハードコーディング・監視などのセキュリティ原則を徹底する
- 本番適用前にパーサーツールで式を検証する
概要
Cronジョブは現代の自動化の心臓部ですが、その構文は熟練したシステム管理者にとっても難解な場合があります。当サイトのオンラインCron解析器は、スケジューリングにおける推測を排除するように設計されています。暗号のようなCron式を明確で人間が理解できる言葉に翻訳することで、このツールはスケジュールされたタスクが意図した通りに実行されることを保証します。バックアップ、クリーンアップスクリプト、自動メールの管理など、正確さが最も重要です。
主な機能
- リアルタイム翻訳: 入力したCron式の意味を、即座に平易な言葉(または選択した言語)で確認できます。
- 次回の実行時間: 今後の実行予定時間のリストを表示し、ロジックを検証できます。
- 全フィールドに対応: 秒(6フィールド)や年(7フィールド)のバリエーションを含む標準的なCron形式を処理します。
- 構文ハイライト: 視覚的なヒントにより、分、時、日、月、曜日を簡単に識別できます。
使い方
- 入力: メインフィールドにCron式を貼り付けるか入力します。
- 確認: 入力に合わせて、人間が理解できる翻訳が自動的に更新されます。
- 検証: 「次回の実行時間」リストをチェックして、要件と一致しているか確認します。
- コピー: ゼロから作成する場合は、提供されている例を使用してください。
主な活用シーン
- サーバーメンテナンス: 毎晩のデータベースバックアップやログローテーションのスケジューリング。
- Web開発: LaravelやDjangoなどのフレームワークでの定期的なバックグラウンドジョブの設定。
- DevOps: CI/CDパイプラインや自動ヘルスチェックの設定。
- 個人の生産性: ローカルマシンでの定期的なリマインダーやスクリプト実行の管理。
技術的背景
Cron式は、空白で区切られた5〜7個のフィールドで構成されます。各フィールドは時間単位(分、時、日、月、曜日)を表します。当サイトの解析器は、*(任意)、,(リスト)、-(範囲)、/(増分)、L(最後)などの特殊文字を処理する堅牢なロジックエンジンを使用しています。うるう年や月の長さを考慮して、次の実行タイミングを正確に計算します。
よくある質問
- 秒はサポートしていますか? はい、秒を含む6フィールドのCron式をサポートしています。
- @dailyなどの非標準エイリアスは使えますか? はい、一般的なエイリアスに対応しています。
- タイムゾーンに対応していますか? デフォルトではUTCに基づいて計算されますが、必要に応じて視点を調整できます。
制限事項
- 実装の違い: システム(Quartz、AWS、Jenkinsなど)によってCron構文には微妙な違いがあります。常に特定のプラットフォームで確認してください。
- エッジケース: 「月末日」(L)や「最近の平日」(W)の挙動は、オペレーティングシステムによって異なる場合があります。