crontabの書き方がわからず、定期実行の設定で手が止まっていませんか。フィールドの意味やアスタリスクの使い方を正しく理解すれば、スケジュール指定はそれほど難しくありません。
この記事では、crontabの書き方を基本構文から実践的なスケジュール設定例まで順を追って解説します。crontabコマンドの操作方法や、設定時に陥りやすいトラブルへの対処法も紹介しているため、初めてcronを扱う方でもすぐに定期実行を始められます。
目次
- crontabの書き方の基本構文
- 5つの時刻フィールドの意味
- アスタリスク(*)の意味
- カンマ(,)で複数の値を指定する書き方
- ハイフン(-)で範囲を指定する書き方
- スラッシュ(/)で間隔を指定する書き方
- crontabの書き方でよく使うスケジュール設定例
- 毎分実行する書き方
- 毎日決まった時刻に実行する書き方
- 毎週特定の曜日に実行する書き方
- 毎月特定の日に実行する書き方
- 複数の条件を組み合わせる書き方
- crontabの書き方で使える特殊文字列
- @rebootでサーバー起動時に実行する
- @daily・@weekly・@monthlyで定期実行する
- crontabの書き方に必要なコマンド操作
- crontab -eで編集する
- crontab -lで現在の設定を確認する
- crontab -rで設定を削除する
- crontabの書き方で起きやすいトラブルと対処法
- コマンドが見つからない(command not found)
- 実行結果のメールが大量に届く
- パーセント記号(%)がエラーになる
- cronデーモンが停止している
- crontabの書き方に関するよくある質問
- cronとcrontabの違いは何ですか
- crontabの設定はどこに保存されますか
crontabの書き方の基本構文
crontab -eで編集するユーザーごとのcrontabは、5つの時刻フィールドと実行コマンドで構成されます。各フィールドはスペースまたはタブで区切り、左から「分・時・日・月・曜日」の順に記述します。なお、システム全体の設定ファイル(/etc/crontab等)はフォーマットが異なり、実行ユーザー名を指定するフィールドが追加されます(詳細は後述のFAQを参照してください)。
5つの時刻フィールドの意味
ユーザーcrontabの1行は、5つの時刻フィールドに続けて実行したいコマンドを記述する形式です。cronは「分・時・月」が現在時刻と一致し、さらに「日」または「曜日」の少なくとも一方が一致したタイミングでコマンドを実行します。
# 分 時 日 月 曜日 コマンド
* * * * * 実行したいコマンド
各フィールドの役割と指定可能な値は次のとおりです。なお、「日」と「曜日」の両方を*以外で指定した場合は、AND条件ではなくOR条件として扱われる実装が一般的で、どちらか一方が合致すればコマンドが実行されます。
| フィールド | 指定範囲 | 補足 |
|---|---|---|
| 分 | 0〜59 | 省略不可 |
| 時 | 0〜23 | 24時間表記 |
| 日 | 1〜31 | 月によって上限が異なる |
| 月 | 1〜12 | 英名3文字でも可(jan等) |
| 曜日 | 0〜7 | 0と7はどちらも日曜 |
Commands are executed by cron(8) when the 'minute', 'hour', and 'month of the year' fields match the current time, and at least one of the two 'day' fields ('day of month', or 'day of week') match the current time.
アスタリスク(*)の意味
アスタリスク(*)は「そのフィールドで許可されたすべての値」を表す指定です。たとえば「時」フィールドに*を指定すると、0時から23時までの毎時という意味になります。
# 毎時0分にbackup.shを実行
0 * * * * /home/user/backup.sh
上記の例では、「分」が0で固定され、残りの4フィールドがすべて*のため、毎日毎時0分にコマンドが実行されます。5つすべてを*にすると毎分実行になるため、意図しない負荷をかけないよう注意してください。
カンマ(,)で複数の値を指定する書き方
カンマで区切ると、1つのフィールドに複数の値を列挙できます。リスト指定と呼ばれる記法で、不規則な時刻を並べたいときに使います。
# 毎日9時、12時、18時にreport.shを実行
0 9,12,18 * * * /home/user/report.sh
この例では「時」フィールドに9,12,18を指定しているため、1日3回だけコマンドが実行されます。カンマの前後にスペースを入れるとフィールドの区切りと誤認されるため、スペースなしで続けて記述してください。
ハイフン(-)で範囲を指定する書き方
ハイフンを使うと、連続した値の範囲をまとめて指定できます。開始値と終了値の両端を含む指定(inclusive)です。
# 平日(月〜金)の8時にstart.shを実行
0 8 * * 1-5 /home/user/start.sh
上記では「曜日」フィールドに1-5を指定し、月曜日から金曜日までを範囲として表現しています。1つずつカンマで列挙する書き方(1,2,3,4,5)と同じ意味ですが、連続する値にはハイフンを使うほうが簡潔に記述できます。
スラッシュ(/)で間隔を指定する書き方
スラッシュは「ステップ値」と呼ばれ、フィールド内の値を一定間隔で飛ばしながら指定するときに使います。たとえば分フィールドの*/10は、0分から始まって10分刻み(0,10,20,30,40,50)を意味し、範囲指定と組み合わせることも可能です。
# 10分ごとにhealth_check.shを実行(0,10,20,30,40,50分に実行)
*/10 * * * * /home/user/health_check.sh
# 9時〜17時の間で2時間ごとにsync.shを実行(9,11,13,15,17時に実行)
0 9-17/2 * * * /home/user/sync.sh
注意点として、ステップ値は「前回実行から常にn分後」という経過時間の指定ではなく、フィールド内での刻み指定です。たとえば*/35は「35分ごと」ではなく「毎時0分と35分」(0,35)の意味になります。大きなステップ値を指定する場合は、展開結果をあらかじめ確認しておくと安全です。
As noted above, skip values only operate within the time period they're attached to. For example, specifying "*/35" for the minute field of a crontab entry won't cause that entry to be executed every 35 minutes; instead, it will be executed twice every hour, at 0 and 35 minutes past.
— crontab(5) - Linux manual page
crontabの書き方でよく使うスケジュール設定例
基本構文を理解したら、実際の運用でよく使うパターンを確認しておくと設定作業がスムーズに進みます。以下では頻出のスケジュール指定をケース別に紹介します。
毎分実行する書き方
動作テストや監視スクリプトの検証で一時的に使うケースが多い設定です。5つのフィールドをすべてアスタリスクにすると、1分ごとにコマンドが実行されます。
# 毎分実行(テスト用途向け)
* * * * * /home/user/test.sh
本番環境でこの設定を常用すると、ログファイルの肥大化やサーバー負荷の上昇を招く場合があります。テスト完了後は必ず設定を削除するか、適切な間隔に変更してください。
毎日決まった時刻に実行する書き方
バックアップやログローテーションなど、1日1回実行したいジョブに使う設定です。「分」と「時」を固定し、残りのフィールドを*にします。
# 毎日午前3時0分にbackup.shを実行
0 3 * * * /home/user/backup.sh
深夜帯に設定するとサーバー負荷の低い時間帯で処理を実行できます。ただし、サマータイムを採用している環境では、切り替え時刻前後のジョブが二重実行またはスキップされる可能性がある点に留意してください。
毎週特定の曜日に実行する書き方
週次レポートの生成やメンテナンスタスクなど、週に1回だけ実行したい場合の設定です。「曜日」フィールドに0〜7の数値または英名3文字(sun, mon等)を指定します。
# 毎週月曜の午前9時にweekly_report.shを実行
0 9 * * 1 /home/user/weekly_report.sh
# 毎週日曜の午前2時にmaintenance.shを実行
0 2 * * sun /home/user/maintenance.sh
Cronie/Vixie cron系では0と7のどちらも日曜日として扱われます。ただし、実装差を避けたい場合は0またはsunに統一するほうが無難です。
毎月特定の日に実行する書き方
月次処理として請求データの集計や月初のバッチ処理を設定する場合は、「日」フィールドに日付を指定します。
# 毎月1日の午前0時にmonthly_batch.shを実行
0 0 1 * * /home/user/monthly_batch.sh
# 毎月15日と28日の午前0時にinvoice.shを実行
0 0 15,28 * * /home/user/invoice.sh
crontabには月末そのものを直接指定する標準記法がありません。月末に実行したい場合は、月末候補日(28〜31日)に毎日起動し、スクリプト側で「翌日が1日か」を判定する方法がよく使われます。以下はLinuxのGNU dateを使った例です(%はcrontab内でエスケープが必要で、詳しくは後述の「パーセント記号(%)がエラーになる」を参照してください)。
# 月末に実行する例(GNU date依存・macOS/BSDでは動作しない)
0 0 28-31 * * [ "$(date +\%d -d tomorrow)" = "01" ] && /home/user/monthend.sh
この-dオプションはGNU coreutilsのdateコマンド固有の機能です。macOSやBSD環境ではdate -v+1d +\%dのように書式が異なるため、対象環境に合わせて使い分けてください。
複数の条件を組み合わせる書き方
カンマ・ハイフン・スラッシュは同一フィールド内で組み合わせて使えます。複雑なスケジュールもフィールドの組み合わせで表現可能です。
# 平日の9時〜18時の間、30分ごとにcheck.shを実行
0,30 9-18 * * 1-5 /home/user/check.sh
# 1月と7月の1日、午前6時にsemiannual.shを実行
0 6 1 1,7 * /home/user/semiannual.sh
前述のとおり、「日」フィールドと「曜日」フィールドの両方を*以外にした場合はOR条件として動作します。たとえば0 0 1 * 5は「毎月1日」と「毎週金曜」の両方で実行されるため、意図しないスケジュールにならないよう確認してください。
If both fields are restricted (i.e., do not contain the "*" character), the command will be run when either field matches the current time. For example, "30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.
— crontab(5) - Linux manual page
crontabの書き方で使える特殊文字列
5つの時刻フィールドの代わりに、@から始まる特殊文字列(ニックネーム)を使用できます。よく使うスケジュールパターンをわかりやすく記述したい場合に便利です。
@rebootでサーバー起動時に実行する
@rebootは、厳密にはcronデーモン(cronの処理を常駐して管理するバックグラウンドプロセス)が起動したタイミングでコマンドを実行する指定です。実務上はサーバー起動時の初期化処理に使われることが多いですが、OSの起動順序やcronの再起動の影響を受ける点に注意してください。
# cronデーモン起動時にstart_app.shを実行
@reboot /home/user/start_app.sh
依存サービスが必要な処理では、単純なsleepだけに頼るのは脆い方法です。対象サービスの起動確認をスクリプト内に組み込むか、systemd環境であればsystemd service/timerで依存関係を明示するほうが確実です。
@daily・@weekly・@monthlyで定期実行する
頻出の定期実行パターンは特殊文字列に置き換えると、視認性が上がり設定ミスを減らせます。各文字列が展開される時刻フィールドは以下のとおりです。
# 以下は 0 0 * * * と同じ(毎日0時0分に実行)
@daily /home/user/daily_job.sh
# 以下は 0 0 * * 0 と同じ(毎週日曜0時0分に実行)
@weekly /home/user/weekly_job.sh
# 以下は 0 0 1 * * と同じ(毎月1日0時0分に実行)
@monthly /home/user/monthly_job.sh
@yearlyは0 0 1 1 *(毎年1月1日0時0分)に、@hourlyは0 * * * *(毎時0分)にそれぞれ展開されます。@annuallyは@yearlyの別名です。これらの特殊文字列はすべて実行時刻が0時0分(@hourlyは0分)固定のため、時刻を変更したい場合は通常の5フィールド形式で記述してください。
crontabの書き方に必要なコマンド操作
crontabファイルの編集・確認・削除には、crontabコマンドを使います。直接ファイルを編集するのではなく、コマンド経由で操作するのがユーザーcrontabの基本的な運用方法です。
crontab -eで編集する
crontab -eは現在のユーザーのcrontabファイルをテキストエディタで開くコマンドです。環境変数VISUALまたはEDITORに設定されたエディタが起動し、保存して終了すると編集内容がcrontabとしてインストールされ、cronが以後その設定に従ってジョブを実行します。
# crontabを編集する
crontab -e
# エディタをvimに指定して編集する場合
EDITOR=vim crontab -e
# 構文だけ先に検証する(Cronie系で利用可能)
crontab -T crontab_draft.txt
初回実行時にエディタの選択を求められる環境もあります。Cronie系の環境では-Tオプションで構文テストだけを実行でき、インストール前にエラーを検出できます。
-T Test the crontab file syntax without installing it.
crontab -lで現在の設定を確認する
crontab -lは現在登録されているcrontabの内容を標準出力に表示するコマンドです。設定した内容が正しく反映されているかを確認する際に使います。
# 現在のcrontab設定を表示
crontab -l
# 他のユーザーのcrontabを確認(root権限が必要)
sudo crontab -u username -l
-uオプションでユーザー名を指定すると、他のユーザーのcrontab設定を確認できます。ただしroot権限が必要なため、一般ユーザーは自分自身の設定のみ閲覧可能です。
crontab -rで設定を削除する
crontab -rは現在のユーザーのcrontab設定をすべて削除するコマンドです。特定の行だけを削除するオプションはなく、crontabファイル全体が消去されます。「e(編集)」と「r(削除)」のキーが隣接しているため、crontab -eのタイプミスで誤って全消去してしまう事故が実務でも多発しています。
# crontab設定をすべて削除
crontab -r
# 削除前に確認プロンプトを表示(Cronie系の-iオプション)
crontab -ri
-iオプションはCronie系の拡張機能であり、すべてのcron実装で利用できるとは限りません。実装差に関係なく安全に運用するには、削除前にcrontab -l > cron_backup.txtのようにバックアップを取得しておくのが確実です。誤って-rを実行した場合でもcrontab cron_backup.txtで復元できます。
crontabの書き方で起きやすいトラブルと対処法
構文は正しいのにジョブが動かないというケースは少なくありません。crontab特有の実行環境に起因するトラブルが多いため、代表的な原因と対処法を確認しておきましょう。
コマンドが見つからない(command not found)
cron経由で実行する場合、ログインシェルと同じ環境変数がそのまま使われるとは限らず、PATHが不足して「command not found」になることがあります。cronが自動設定する環境変数はSHELL・LOGNAME・HOME程度で、PATHの内容は環境依存です。
# 対処法1: コマンドを絶対パスで指定する
0 3 * * * /usr/local/bin/python3 /home/user/script.py
# 対処法2: crontab内でPATHを定義する
PATH=/usr/local/bin:/usr/bin:/bin
0 3 * * * python3 /home/user/script.py
実行ファイルの場所はcommand -v python3やwhich python3で確認し、cronではできるだけ絶対パスで書くと安全です。crontabファイルの先頭にPATH環境変数を定義しておくと、以降のすべてのジョブに適用されるため個別に絶対パスを書く手間を省けます。
実行結果のメールが大量に届く
cronは、ジョブの標準出力・標準エラー出力がある場合にメール送信を試みる実装が一般的です。MAILTOが設定されておらず、かつローカルMTA(メール転送エージェント)が利用可能な環境では、出力内容がcrontabの所有者宛てにメールされることがあります。
# 出力をログファイルに記録し、メール送信を抑止する
*/10 * * * * /home/user/job.sh >> /var/log/job.log 2>&1
# 出力を完全に破棄する
*/10 * * * * /home/user/job.sh > /dev/null 2>&1
# crontab全体でメール送信を無効にする
MAILTO=""
メール通知を使わない運用では、必要な出力はログにリダイレクトし、不要な出力だけを/dev/nullに捨てる構成にすると管理しやすくなります。標準出力のみ破棄して標準エラー出力はログに残す構成(/home/user/job.sh > /dev/null 2>> /var/log/job_error.log)にすれば、障害の検知が遅れるリスクも軽減できます。なお、MAILTO=""を指定するとエラー時の通知も含めてすべて無効化されるため、スクリプト内でのエラーハンドリングやログ監視など別の通知手段が用意されている場合のみ使用してください。
パーセント記号(%)がエラーになる
crontab内のコマンド部分では、パーセント記号(%)は改行文字として解釈される特殊文字です。最初の%以降のテキストはコマンドの標準入力として送られるため、dateコマンドなどで%Yや%mを使う場合はバックスラッシュでエスケープしないと正しく動作しません。
# NG: %がそのまま記述されている
0 0 * * * echo "$(date +%Y-%m-%d)" >> /var/log/date.log
# OK: %をバックスラッシュでエスケープ
0 0 * * * echo "$(date +\%Y-\%m-\%d)" >> /var/log/date.log
# OK: シェルスクリプトにまとめて実行する(エスケープ不要)
0 0 * * * /home/user/log_date.sh
%のエスケープ漏れはcrontab特有の落とし穴として非常に多いミスです。コマンドが複雑になる場合はシェルスクリプトに処理を切り出し、crontabからはそのスクリプトを呼び出す形にすると、エスケープの問題を回避しつつ可読性も向上します。
A "%" character in the command, unless escaped with a backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.
— crontab(5) - Linux manual page
cronデーモンが停止している
crontabの設定に問題がなくてもジョブが実行されない場合は、cronデーモン自体が停止している可能性があります。cronのサービス名はディストリビューションによって異なるため、対象環境に合ったコマンドで確認してください。
# Debian / Ubuntu系
systemctl status cron
sudo systemctl start cron
sudo systemctl enable cron
# RHEL / CentOS / Fedora系
systemctl status crond
sudo systemctl start crond
sudo systemctl enable crond
systemdを使わない古い環境では、Debian/Ubuntu系はservice cron status、RHEL/CentOS系はservice crond statusが一般的です。ログの確認先もディストリビューションにより異なり、systemd環境ではまずjournalctl -u cron(RHEL系はjournalctl -u crond)を確認し、必要に応じてDebian/Ubuntu系では/var/log/syslog、RHEL系では/var/log/cronも参照してください。
crontabの書き方に関するよくある質問
cronとcrontabの違いは何ですか
cronはLinux/Unixシステムに常駐し、スケジュールに従ってコマンドを自動実行するデーモン(バックグラウンドプロセス)です。一方のcrontabは、コマンド名としてはcronに実行させるスケジュールを登録・管理するユーティリティを指し、同時にcronが読み取るテーブルファイルの総称でもあります。
# cronデーモンの状態を確認(Debian/Ubuntu系の場合)
systemctl status cron
# crontabコマンドで自分のスケジュールを表示
crontab -l
つまりcronが「実行するエンジン」であり、crontabが「スケジュール表およびその管理ツール」という関係です。日常の運用ではcrontabコマンドを使ってスケジュールを編集し、cronデーモンがそのスケジュールを読み取って定期的にコマンドを実行する流れになります。
crontabの設定はどこに保存されますか
crontab -eで編集したユーザーごとの設定ファイルは、一般的に/var/spool/cron/ディレクトリ配下にユーザー名のファイルとして保存されます。システム全体のcrontabは/etc/crontabに配置されており、こちらはユーザー名フィールドが追加された6フィールド形式で記述されています。
# ユーザーごとのcrontabファイルの保存先(ディストリビューションにより異なる)
/var/spool/cron/crontabs/username # Debian/Ubuntu系
/var/spool/cron/username # RHEL/CentOS系
# システム全体のcrontab
/etc/crontab
/etc/cron.d/ # システム用の追加設定
ユーザーごとのcrontab(spool配下のファイル)は、直接編集せずcrontab -eで管理するのが原則です。一方で、/etc/crontabや/etc/cron.d/配下のシステム用crontabはrootが直接テキストエディタで編集する運用が一般的です。つまり、自分の定期実行設定はcrontab -eで、システム全体の設定は/etc/crontab等をroot権限で編集するという使い分けが基本になります。
※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。
ITやプログラミングに関するコラム
PythonをWebで実行する方法
共通テスト「情報Ⅰ」2年目で変わる、日本の教育と学び方
gitでブランチ(branch)を切り替える方法
git cloneでブランチを指定する方法
64GBのメモリが必要な人・不要な人の特徴
PCを再起動するコマンド一覧
CapsLock以外で大文字になる原因【Windows編】
パソコンで大文字になるのを解除する方法
面白いAIの活用事例を業界別に紹介
Gitでcommit(コミット)を取り消す方法
ITやプログラミングに関するニュース
サイボウズがkintone AIを正式提供、β版から約1年を経てクレジット制を導入
ロゼッタのラクヤクAIがCSRドラフト作成期間を90%以上短縮、従来4週間を約2日に
AI CROSSが不動産業界向け生成AI伴走支援を開始、アスコットの業務AI実装を実践サポート
日本情報クリエイトが「オーナー提案AIロボⅡ」売買査定を刷新、月1万円からW査定が回数無制限に
Wur株式会社がAI新規事業診断サービス「MVP事業診断レポート」をリリース、12の質問で事業構想を約10分で分析
バトンズがM&A専門家向け「AI概要書」β版を提供開始、企業概要書のドラフトを最速3分で自動生成
SCSKが観光DXサービス「Connexia」を開発、首里城公園でNFT活用の周遊促進が始動
Verdent AI発表、エンジニア不要でソフトウェアを構築する「AIエンジニアリングチーム」が登場
ゼネラルBREXAテクノロジーが外食・小売向けAIサービス「aimana」を開発、店長の意思決定をデータで支援
田中組がKencopa工程AIエージェント製品版を先行利用開始、建設現場の工程管理属人化を解消へ
