- 技術 💻
cronの書き方|設定例30パターンの早見表と落とし穴まとめ
cronは、決めた日時にコマンドを自動で実行するLinuxの仕組みです。設定は crontab -e で開くファイルに「いつ(5つの時刻欄)」と「何を(コマンド)」を1行で書くだけで、バックアップ、ログの整理、定期レポートなどを自動化できます。
書き方自体はシンプルですが、「設定したのに動かない」「思った日と違う日に動いた」というトラブルが非常に多い仕組みでもあります。この記事では、基本の書き方と設定例30パターンの早見表に加えて、ハマりやすい落とし穴、動かないときの確認手順、GitHub ActionsやKubernetesなどcron式の方言の違いまでをまとめました。
cronの基本の書き方
crontabの1行は、5つの時刻欄+実行するコマンドでできています。
分 時 日 月 曜日 コマンド
* * * * * /path/to/command
| 欄 | 範囲 | 補足 |
|---|---|---|
| 分 | 0〜59 | |
| 時 | 0〜23 | 24時間表記 |
| 日 | 1〜31 | |
| 月 | 1〜12 | JAN〜DECの英語表記も可 |
| 曜日 | 0〜7 | 0と7が日曜日。SUN〜SATの英語表記も可 |
使える記号
| 記号 | 意味 | 例 | 例の意味 |
|---|---|---|---|
* |
すべて | * * * * * |
毎分 |
, |
複数指定 | 0 9,18 * * * |
9時と18時 |
- |
範囲 | 0 9 * * 1-5 |
月〜金の9時 |
/ |
間隔 | */15 * * * * |
15分ごと |
- と / |
範囲内の間隔 | 0-30/10 * * * * |
0・10・20・30分 |
省略形(@で始まる書き方)
| 省略形 | 意味 | 同じ意味の5欄表記 |
|---|---|---|
@reboot |
起動時に1回 | (対応する表記なし) |
@hourly |
毎時0分 | 0 * * * * |
@daily / @midnight |
毎日0時0分 | 0 0 * * * |
@weekly |
毎週日曜0時0分 | 0 0 * * 0 |
@monthly |
毎月1日0時0分 | 0 0 1 * * |
@yearly / @annually |
毎年1月1日0時0分 | 0 0 1 1 * |
設定例30パターン早見表
コピーして、コマンド部分だけ置き換えて使えます。
分・時間ごと
| やりたいこと | 書き方 |
|---|---|
| 毎分 | * * * * * |
| 5分ごと | */5 * * * * |
| 15分ごと | */15 * * * * |
| 30分ごと | */30 * * * * |
| 毎時0分 | 0 * * * * |
| 毎時30分 | 30 * * * * |
| 2時間ごと(0分) | 0 */2 * * * |
| 6時間ごと(0時・6時・12時・18時) | 0 */6 * * * |
| 9時〜18時の毎時0分 | 0 9-18 * * * |
| 平日の9時〜18時、10分ごと | */10 9-18 * * 1-5 |
毎日
| やりたいこと | 書き方 |
|---|---|
| 毎日0時 | 0 0 * * * |
| 毎日3時30分 | 30 3 * * * |
| 毎日9時と18時 | 0 9,18 * * * |
| 毎日23時59分 | 59 23 * * * |
曜日
| やりたいこと | 書き方 |
|---|---|
| 平日(月〜金)の9時 | 0 9 * * 1-5 |
| 土日の10時 | 0 10 * * 0,6 |
| 毎週月曜の8時 | 0 8 * * 1 |
| 毎週金曜の17時 | 0 17 * * 5 |
| 月・水・金の7時 | 0 7 * * 1,3,5 |
月・日
| やりたいこと | 書き方 |
|---|---|
| 毎月1日の0時 | 0 0 1 * * |
| 毎月15日の12時 | 0 12 15 * * |
| 毎月1日と15日の0時 | 0 0 1,15 * * |
| 四半期の初日(1・4・7・10月の1日)の0時 | 0 0 1 1,4,7,10 * |
| 毎年1月1日の0時 | 0 0 1 1 * |
| 毎年4月1日の9時 | 0 9 1 4 * |
5欄だけでは書けないもの(コマンド側で判定)
| やりたいこと | 書き方 |
|---|---|
| 毎月末日の23時 | 0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && コマンド |
| 毎月第1月曜の9時 | 0 9 1-7 * * [ "$(date +\%u)" = "1" ] && コマンド |
| 毎月最終金曜の18時 | 0 18 * * 5 [ "$(date -d '+7 days' +\%m)" != "$(date +\%m)" ] && コマンド |
| 30秒ごと | * * * * * コマンド と * * * * * sleep 30; コマンド の2行 |
| 起動時に1回 | @reboot コマンド |
末日・第1月曜・最終金曜の例は、GNU版の date を前提にしています(多くのLinuxディストリビューションの標準)。
第1月曜を 0 9 1-7 * 1 と書かないでください。 次の落とし穴で説明するとおり、「1〜7日」または「月曜日」のどちらかに当てはまれば実行されてしまいます。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「cronの書き方|設定例30パターンの早見表と落とし穴まとめ」
ハマりやすい落とし穴7つ
1. 日と曜日を両方指定すると「OR条件」になる
もっとも誤解が多い仕様です。
0 9 1-7 * 1
「1〜7日のうちの月曜日(=第1月曜)」のつもりで書いても、実際は「1〜7日の毎日」と「毎週月曜日」の両方で実行されます。日と曜日の欄が両方とも * 以外のときは、どちらか一方に当てはまれば実行される(OR条件)のが、一般的なcronの仕様です。
「かつ(AND)」にしたいときは、どちらかを * にし、もう一方の条件はコマンド側で判定します(早見表の「第1月曜」の書き方)。
2. % は改行扱いになる
crontabのコマンド部分では、% が改行として扱われます(% 以降は標準入力に渡されます)。日付をファイル名に入れる定番の書き方は、そのままだと動きません。
# × % が改行扱いになり、コマンドが途中で切れる
0 3 * * * tar czf /backup/data_$(date +%Y%m%d).tar.gz /data
# ○ % の前に \ を付ける
0 3 * * * tar czf /backup/data_$(date +\%Y\%m\%d).tar.gz /data
3. 手で打つと動くのに、cronだと動かない(PATH)
cronは、ログインしたときとは違う最小限の環境変数でコマンドを実行します。PATHは /usr/bin:/bin 程度しか通っていないことが多く、手で実行すると動くコマンドが「command not found」になります。
対策は次のどちらかです。
- コマンドをフルパスで書く(
which コマンド名でパスを確認) - crontabの先頭で環境変数を設定する
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
0 3 * * * backup.sh
同じ理由で、シェルの設定ファイル(.bashrc など)で設定した変数や別名も、cronでは使えません。スクリプトの中で必要な環境を設定するのが確実です。
4. タイムゾーンがずれている
cronは基本的にサーバーのタイムゾーンで動きます。クラウドのサーバーやコンテナは、初期設定がUTC(協定世界時)のことが多く、日本時間の9時のつもりで 0 9 * * * と書くと、日本時間の18時に実行されます。
timedatectl # サーバーのタイムゾーンを確認
date # 現在時刻の表示でも確認できる
一部の実装(RHEL系で使われるcronieなど)では、crontabの先頭に CRON_TZ=Asia/Tokyo と書いて、ジョブのタイムゾーンを指定できます。
5. 出力を捨てると、失敗に気づけない
cronは、コマンドの出力をメール(MAILTO宛て)で送ろうとします。メールの設定がないサーバーでは、エラーが誰にも届かず消えていきます。ログファイルに残すのが基本です。
0 3 * * * /home/app/backup.sh >> /var/log/app/backup.log 2>&1
2>&1 で、エラー出力も同じファイルに記録されます。> /dev/null 2>&1 で出力を捨てる書き方もよく見かけますが、失敗に気づけなくなるので、捨てるのは結果を別の方法で監視している場合だけにします。
ログを書き続けるとファイルが大きくなるので、ローテーションもあわせて設定します。消し方を間違えると容量が減らないことがあるので、「Linuxでrmしても容量が減らない原因と対処法」もあわせてどうぞ。
6. 前の実行が終わる前に、次が始まる
5分ごとのジョブが、たまたま6分かかると、同じ処理が2本同時に動きます。データの二重処理や、負荷の急増の原因になります。
flock で、前の実行が終わっていなければスキップさせます。
*/5 * * * * flock -n /tmp/sync.lock /home/app/sync.sh
-n は「ロックが取れなければ待たずに終了する」という意味です。
7. crontab -r で全部消える
crontab -r は、確認なしでその利用者のcrontabをすべて削除します。キーボードで e の隣に r があるため、crontab -e のつもりで打ち間違える事故が起きます。
- 編集前にバックアップを取る習慣をつける:
crontab -l > ~/crontab_backup.txt crontab -i -rのように-iを付けると、削除前に確認してくれます(対応している実装の場合)
crontabの操作コマンド
| コマンド | 意味 |
|---|---|
crontab -e |
自分のcrontabを編集する |
crontab -l |
自分のcrontabを表示する |
crontab -l > ファイル |
内容をファイルにバックアップする |
crontab ファイル |
ファイルの内容でcrontabを置き換える |
crontab -r |
自分のcrontabを削除する(確認なし) |
sudo crontab -u ユーザー名 -l |
別のユーザーのcrontabを表示する |
書く場所は3種類ある
| 書く場所 | 書式 | 用途 |
|---|---|---|
crontab -e(ユーザーごと) |
5欄+コマンド | 個人・アプリ用のジョブ |
/etc/crontab |
5欄+実行ユーザー+コマンド | システム全体の設定 |
/etc/cron.d/ 配下のファイル |
5欄+実行ユーザー+コマンド | パッケージやアプリごとに分けて管理 |
/etc/crontab と /etc/cron.d/ では、時刻欄とコマンドの間に実行ユーザーを書く必要があります。ユーザーごとのcrontabと同じ書き方をすると、コマンドの先頭がユーザー名として解釈されて動きません。
# /etc/cron.d/backup の例
0 3 * * * app /home/app/backup.sh >> /var/log/app/backup.log 2>&1
Debian・Ubuntuでは、/etc/cron.d/ のファイル名に .(ドット)を含めると読み込まれません。backup.cron ではなく backup のような名前にします。
cronが動かないときの確認手順
上から順に確認すると、ほとんどの原因にたどり着けます。
1. cronのサービスが動いているか
systemctl status cron # Debian・Ubuntu
systemctl status crond # RHEL・CentOS・Amazon Linux など
2. cronがジョブを実行したか(ログを見る)
grep CRON /var/log/syslog # Debian・Ubuntu
sudo cat /var/log/cron # RHEL系
journalctl -u cron # systemdのログ(RHEL系は -u crond)
ログに実行の記録がなければ、時刻の指定(タイムゾーン・OR条件)や、書いた場所の書式を確認します。記録があるのに結果が出ていなければ、コマンド側の問題です。
3. コマンド側のエラーを確認する
>> ログファイル 2>&1 で出力を残し、エラーの内容を確認します。多いのは次の3つです。
- PATHが通っていない(落とし穴3)
%がエスケープされていない(落とし穴2)- 実行権限がない(スクリプトに
chmod +xがされていない)
4. cronと同じ環境で手動実行してみる
env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=$HOME /bin/sh -c 'コマンド'
環境変数を最小限にした状態で実行すると、cronで動かない原因を手元で再現できます。
cron式の方言:GitHub Actions・Kubernetes・AWSとの違い
「cron式」はLinuxのcron以外でも使われていますが、サービスごとに細かい違いがあります。ほかの環境の書き方をそのまま持ち込むと、意図しない時刻に動きます。
| 環境 | 欄の数 | タイムゾーン | 主な違い |
|---|---|---|---|
| Linux(cron) | 5欄 | サーバーのタイムゾーン | 最小単位は1分 |
| GitHub Actions(schedule) | 5欄 | 常にUTC | 最短5分間隔。混雑時は実行が遅れることがある |
| Kubernetes(CronJob) | 5欄 | 既定はコントローラーのタイムゾーン | timeZone 欄で指定できる |
| AWS EventBridge(スケジュール) | 6欄(年を含む) | 既定はUTC | 日と曜日の一方に ? を指定する |
| Quartz(Javaのライブラリ) | 6〜7欄(秒を含む) | 設定による | 先頭が「秒」。日と曜日の一方に ? を指定する |
特にGitHub Actionsは常にUTCなので、日本時間の9時に動かしたいときは 0 0 * * *(UTCの0時=日本時間の9時)と書きます。
cronとsystemdタイマーの使い分け
最近のLinuxでは、cronの代わりにsystemdタイマーを使う方法もあります。
| 観点 | cron | systemdタイマー |
|---|---|---|
| 設定の手軽さ | 1行で書ける | 設定ファイルが2つ必要(.timer と .service) |
| 止まっていた間の実行 | 実行されない | Persistent=true で、起動後に取りこぼした分を実行できる |
| ログ | 自分で出力先を設定 | journalに自動で記録される |
| 多重起動 | flock等で自分で防ぐ | 同じサービスは二重に起動しない |
手軽さならcron、確実性や管理のしやすさを重視するならsystemdタイマー、という使い分けが一般的です。
よくある質問
Q. 秒単位で実行できますか?
A. cronの最小単位は1分です。30秒ごとなら、sleep 30 を使った2行で実現できます(早見表参照)。それより細かい間隔が必要なら、常駐プログラムやsystemdタイマーを検討します。
Q. サーバーが止まっていた時間のジョブはどうなりますか? A. cronでは実行されず、そのまま飛ばされます。止まっていた間の分も実行したい場合は、anacronやsystemdタイマー(Persistent=true)を使います。
Q. 同じ時刻に大量のジョブを設定しても大丈夫ですか? A. 毎時0分などに処理が集中すると、サーバーや接続先に負荷が集中します。重要度の低いジョブは、7分・23分のように実行時刻をずらすのがおすすめです。
Q. crontabの設定は反映に再起動が必要ですか?
A. crontab -e で保存すれば、再起動なしで反映されます。
まとめ
- cronは「分 時 日 月 曜日 コマンド」の1行で書く
- 日と曜日を両方指定するとOR条件。「第1月曜」などはコマンド側で判定する
%は\%にエスケープ、コマンドはフルパスで書く- サーバーのタイムゾーンを確認する。GitHub Actionsは常にUTC
- 出力は
>> ログ 2>&1で残し、flockで多重起動を防ぐ - 動かないときは、サービス → ログ → コマンドの順に確認する
あわせて読みたい関連記事
- Linuxでrmしても容量が減らない原因と対処法
- git reset --hardを取り消す方法|reflogで復元する手順
- APIキーをGitHubにpushしてしまった時の対処手順
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「cronの書き方|設定例30パターンの早見表と落とし穴まとめ」
株式会社RJCでは、保険・金融・決済などのシステム開発を通じて、こうした運用の知識をチームで共有しています。
▶ RJC丸わかり https://www.r-jc.jp/guide/?mediacode=02-00001-003
▶ エントリーはこちら(1〜2分で完了します) https://www.r-jc.jp/recruitment/?mediacode=02-00001-003
株式会社RJC ― SI事業・SES事業・AI駆動開発。未経験からエンジニアに育てるのが得意な会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。