
Linuxサーバーでのデータバックアップ、定期バッチ処理、ログローテーション、SSL証明書更新など、定期的な自動化処理に欠かせないのがcron(クローン)とcrontab(クロンタブ)です。
Linuxを運用する上で必須となる自動化ツールですが、「5つの数値の順番がわからなくなる」「毎日深夜2時に実行する指定はどう書くのか」「手動では実行できるのにcronだと動かない」といった疑問やトラブルに遭遇する方は少なくありません。特に、crontab -r による全削除事故や、実行環境のPATHの違いによる不具合は初心者が一度は経験する落とし穴です。
この記事では、crontabの日時指定ルール(分・時・日・月・曜日)や特殊記号の使い分け、実務で頻出する設定例、安全なコマンド操作手順、そして動かないときの4大原因の切り分けとログ確認方法まで詳しく解説します。
この記事で行うこと
前提条件・対象読者
- 対象読者:Linux環境で定期ジョブやシェルスクリプトを自動化したい方、crontabの書き方や動かない原因を調べたいエンジニア
- 検証対象OS:Ubuntu 26.04 / 24.04 LTS、Debian、AlmaLinux、Rocky Linux、Amazon Linux 2023などの主要Linuxディストリビューション
- 必要な環境:Linuxのターミナル操作ができる環境(一般ユーザー権限、一部システムログ確認にはsudo権限)
【結論】crontabの日時指定構文とよく使う設定例早見表
crontabは、左から「分」「時」「日」「月」「曜日」の5つのフィールドを半角スペース区切りで並べ、その後に実行するコマンドを記述します。
分 時 日 月 曜日 実行コマンド
実務でよく使われる代表的なスケジュール設定を一覧表にまとめました。迷ったときはこの早見表からコピーして活用できます。
| 実行頻度・スケジュール | crontabの指定構文 | 実行タイミングの解説 |
|---|---|---|
| 毎分実行 | * * * * * | 1分ごとに毎分実行(動作確認用) |
| 5分ごと | */5 * * * * | 0分、5分、10分…と5分間隔で実行 |
| 10分ごと | */10 * * * * | 0分、10分、20分…と10分間隔で実行 |
| 15分ごと | */15 * * * * | 0分、15分、30分、45分に実行 |
| 30分ごと | */30 * * * * | 0分、30分に実行 |
| 毎時0分(1時間ごと) | 0 * * * * | 毎時間の0分に実行(1:00, 2:00…) |
| 毎時30分 | 30 * * * * | 毎時間の30分に実行(1:30, 2:30…) |
| 毎日深夜2時0分 | 0 2 * * * | 毎晩深夜2:00に1回実行(日次バックアップ等) |
| 毎日早朝5時30分 | 30 5 * * * | 毎朝5:30に1回実行(日次集計バッチ等) |
| 毎日9時と18時 | 0 9,18 * * * | 出社時と退勤時に合わせた1日2回実行 |
| 平日(月〜金)の朝9時 | 0 9 * * 1-5 | 土日を除く営業日の朝9:00に実行 |
| 毎週日曜日の深夜3時 | 0 3 * * 0 | 週1回の週次メンテナンス実行 |
| 毎月1日の深夜4時 | 0 4 1 * * | 月1回の月次集計・定期レポート作成 |
| システム起動時 | @reboot | サーバー再起動時に自動実行 |
crontabの基本構文(分 時 日 月 曜 コマンド)と特殊記号(* / , -)
crontabの構文を理解する上で重要なのは、5つの時間フィールドの指定範囲と、間隔や複数日時を表現する4つの特殊記号です。
5つの日時フィールドの指定範囲
各フィールドには、以下の範囲の数値または定義文字を指定します。
* * * * * コマンド
┬ ┬ ┬ ┬ ┬
│ │ │ │ └─ 曜日 (0 - 7) ※0と7は日曜日、1:月, 2:火, 3:水, 4:木, 5:金, 6:土
│ │ │ └────── 月 (1 - 12、または JAN - DEC)
│ │ └─────────── 日 (1 - 31)
│ └──────────────── 時 (0 - 23、24時間表記)
└───────────────────── 分 (0 - 59)
各フィールドのポイントは次の通りです。
4つの特殊記号(* / , -)の使い方
複数の時間帯や特定の間隔を指定したい場合、4つの特殊記号を組み合わせて柔軟にスケジュールを組みます。
特殊な時間指定文字列(アットマーク記述)
cron(Vixie cronやcronieなど)には、5つのフィールドの代わりに「@」から始まる特殊なキーワードを指定できるショートカット構文が用意されています。
| 特殊文字列 | 相当する日時構文 | 動作概要 |
|---|---|---|
| @reboot | なし | サーバー起動時に一度だけ実行する |
| @hourly | 0 * * * * | 毎時0分に1回実行 |
| @daily | 0 0 * * * | 毎日深夜0時0分に1回実行 |
| @midnight | 0 0 * * * | 毎日深夜0時0分に1回実行(@dailyと同等) |
| @weekly | 0 0 * * 0 | 毎週日曜日深夜0時0分に1回実行 |
| @monthly | 0 0 1 * * | 毎月1日深夜0時0分に1回実行 |
| @yearly | 0 0 1 1 * | 毎年1月1日深夜0時0分に1回実行 |
特に「@reboot」は、OS再起動時に特定の常駐スクリプトやバックグラウンドプロセスを立ち上げたい場合に重宝します。
実務でよく使うスケジュール設定例(毎日深夜実行、5分ごと、平日のみなど)
実際のサーバー管理や業務システムで頻繁に登場する実用的な設定例をパターン別に紹介します。
パターン1:深夜や早朝の日次メンテナンス・バックアップ
サーバーの負荷が低い深夜・早朝帯に、データベースのダンプやログの圧縮・退避を行う設定です。
# 毎日深夜2時30分にバックアップスクリプトを実行
30 2 * * * /home/ubuntu/scripts/backup.sh
# 毎日早朝4時0分に不要なキャッシュファイルを削除
0 4 * * * /home/ubuntu/scripts/clean_cache.sh
分を「0」や「30」と明確に指定することがポイントです。もし「* 2 * * *」と書いてしまうと、深夜2時台の「毎分(2:00から2:59まで計60回)」実行されてしまうため注意してください。
パターン2:5分・10分・30分間隔のヘルスチェック・定期監視
Webサイトの死活監視や、定期的なキュー処理、外部APIのポーリングなどに使われます。
# 5分ごとに監視スクリプトを実行
*/5 * * * * /home/ubuntu/scripts/health_check.sh
# 10分ごとに未処理キューを処理
*/10 * * * * /usr/bin/python3 /home/ubuntu/app/process_queue.py
# 30分ごと(毎時0分と30分)に実行
0,30 * * * * /home/ubuntu/scripts/sync_data.sh
「*/30 * * * *」と「0,30 * * * *」はどちらも同じ動作になります。
パターン3:平日のみ・業務時間帯のみのバッチ実行
社内業務向けシステムで、土日や夜間の不要なリソース消費・通知を避けたい場合の設定です。
# 平日(月曜日〜金曜日)の朝9時0分に通知を送信
0 9 * * 1-5 /home/ubuntu/scripts/morning_notify.sh
# 平日の9時から17時まで、毎時0分に実行
0 9-17 * * 1-5 /home/ubuntu/scripts/hourly_report.sh
曜日フィールドに「1-5」(月〜金)を指定することで、週末の無駄な実行を防止できます。
パターン4:週次・月次の定期レポート集計
週報や月次データの集計、ログの月次アーカイブなどに使われます。
# 毎週月曜日の早朝5時0分に前週分の集計を実行
0 5 * * 1 /home/ubuntu/scripts/weekly_aggregation.sh
# 毎月1日の深夜3時0分に前月分の月次バッチを実行
0 3 1 * * /home/ubuntu/scripts/monthly_report.sh
crontabの編集・確認・削除コマンド(crontab -e / -l / -r の注意点)
ユーザーごとにcrontabを設定・管理する際は、専用の「crontab」コマンドを使用します。
基本コマンド一覧
| コマンド | 役割・用途 |
|---|---|
crontab -l | 現在登録されているcron設定の一覧を表示する |
crontab -e | 現在のユーザーのcron設定ファイルをエディタで編集する |
crontab -r | 現在のユーザーのcron設定をすべて削除する(取り扱い厳重注意) |
| crontab -u ユーザー名 -l | 指定したユーザーのcron設定を表示する(root権限が必要) |
| crontab -u ユーザー名 -e | 指定したユーザーのcron設定を編集する(root権限が必要) |
初回実行時のエディタ選択と変更方法
Ubuntuなどの環境で初めて「crontab -e」を実行すると、以下のように使用するエディタの選択を求められます。
no crontab for ubuntu - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]:
nanoエディタを使いたい場合は「1」、Vimを使いたい場合は「2」を入力してEnterを押します。
後からエディタを変更したい場合は、以下のコマンドを実行することでいつでも再選択できます。
select-editor
また、環境変数「EDITOR」や「VISUAL」を設定してエディタを固定することも可能です。
export EDITOR=vim
crontab -e
最も危険な罠:crontab -r による全削除事故と防止策
Linuxの運用で最も恐れられているヒューマンエラーの1つが、「crontab -r」の誤実行です。
キーボードの配列上、「e(編集)」と「r(削除)」は隣同士に配置されています。そのため、「設定を確認・編集しようとして crontab -e と打つつもりで誤って crontab -r を実行してしまい、警告なしで設定が全て消去された」という事故が後を絶ちません。
crontab -r は確認プロンプトが出ずに即座に全削除されるシステムが多いため、以下の3つの対策を必ず習慣化してください。
- 編集前に必ずバックアップを取る crontabを編集する前に、必ず現在の設定をファイルに書き出しておきます。
crontab -l > ~/crontab_backup_$(date +%Y%m%d).txt
万が一設定を消してしまっても、以下のコマンドでバックアップから即座に復元できます。
crontab ~/crontab_backup_20260911.txt
- 削除時に確認プロンプトを出すオプション(-i)を活用する 「-i」オプションを付けると、削除前に「crontab: really delete ubuntu’s crontab? (y/n)」と確認を求めてくれます。
crontab -i -r
- シェルのエイリアスで誤爆を防止する ~/.bashrc や ~/.zshrc に以下のエイリアスを登録しておくと安心です。
alias crontab="crontab -i"
設定ファイルの末尾には必ず「改行」を入れる
crontabを編集する際の隠れた注意点として、ファイルの最終行に空の改行(Enterキー)を入れる必要があります。
POSIX標準の仕様やVixie cronの実装により、末尾に改行のない最後の行は「不完全な行」とみなされて読み飛ばされ、実行されないケースがあります。設定を追記した後は、一番下の行で改行して空行が1行ある状態で保存してください。
標準出力・エラー出力のログ保存とメール通知停止(> /dev/null 2>&1)
cronでコマンドが実行された際、画面(ターミナル)は開いていません。そのため、プログラムが出力する標準出力(stdout)やエラーメッセージ(stderr)の行き先を意識して設定する必要があります。
デフォルト動作の問題点とメール通知の停止
デフォルトでは、cronジョブ内で何らかの標準出力やエラー出力が発生すると、cronデーモンはその内容をローカルメール(sendmailやPostfix経由)として実行ユーザー宛てに送信しようとします。
しかし、現代のサーバー環境ではローカルメールサーバーが適切に設定されていないことが多く、以下のような問題が発生します。
もしメール送信が不要である場合は、crontabファイルの先頭に「MAILTO=””」と記載することで、cronからのメール送信を一括で完全に無効化できます。
# メール送信を無効化
MAILTO=""
# 毎日深夜2時に実行(出力があってもメール送信しない)
0 2 * * * /home/ubuntu/scripts/backup.sh
実務での標準的なログ保存設定
メール通知に頼るのではなく、実行結果やエラーを日付ごとのログファイルに正しく書き出して管理するのが実務の定石です。
# 実行結果とエラーをログファイルに追記保存する(推奨)
0 2 * * * /home/ubuntu/scripts/backup.sh >> /var/log/backup.log 2>&1
# 実行ごとにログを上書き保存する(最新の1回分だけ保持したい場合)
0 2 * * * /home/ubuntu/scripts/backup.sh > /var/log/backup.log 2>&1
# 出力もエラーも不要で完全に破棄する
0 2 * * * /home/ubuntu/scripts/backup.sh > /dev/null 2>&1
「> /dev/null 2>&1」の仕組みと読み解き方
よく見かける呪文のような記述「> /dev/null 2>&1」は、以下の2つのシェルリダイレクトが組み合わさったものです。
- 「> /dev/null」:ファイルディスクリプタ1(標準出力)を、書き込まれたデータをすべて破棄する特殊デバイス「/dev/null」に送る設定です。
- 「2>&1」:ファイルディスクリプタ2(標準エラー出力)を、ファイルディスクリプタ1(標準出力)と同じ出力先に統合する設定です。
つまり、「エラーも含めたすべての出力を画面に出さず、完全に破棄して静かに実行する」という意味になります。
日付付きログファイルを作成する際の「%」エスケープの罠
「ログファイル名に実行日付を含めたい」と考え、以下のように記述する方がよくいます。
# 失敗例(動かない)
0 2 * * * /home/ubuntu/scripts/backup.sh >> /var/log/backup_$(date +%Y%m%d).log 2>&1
実は、これは構文エラーとなり動きません。crontab内では「%(パーセント記号)」が特殊文字(改行コード)として解釈される仕様になっているためです。
コマンド行内でdateコマンドの日付フォーマットを使う場合は、必ず「%」のようにバックスラッシュ(円マーク)でエスケープする必要があります。
# 成功例(%をエスケープして指定)
0 2 * * * /home/ubuntu/scripts/backup.sh >> /var/log/backup_$(date +\%Y\%m\%d).log 2>&1
記述が複雑になって可読性が落ちるのを防ぐため、実務では日付付きログの生成処理をシェルスクリプトの内部に記述し、crontab側はシンプルな指定にとどめる設計が推奨されます。
cronが動かない場合の4大原因とトラブルシューティング(PATH、相対パス、権限、実行ログ確認)
手動でターミナルからコマンドを実行すると正常に動くのに、crontabに登録すると動かないというトラブルは日常茶飯事です。
その原因の9割以上は、以下の4大原因に集約されます。問題が起きたときは、上から順にチェックしていきましょう。
原因1:環境変数(PATH)がログインシェルと異なる
cronが動かない原因の第1位は「PATH(環境変数)の不足」です。
ユーザーがSSHでログインしたターミナルでは、~/.bashrc や ~/.profile などが読み込まれ、様々なコマンドパス(/usr/local/bin や /home/ubuntu/.local/bin、anyenv、nvm、pyenvなど)がPATHに通っています。
しかし、cronデーモンがジョブを実行する環境は、非対話型の最小限のシェル環境です。デフォルトのPATHは極めて限定的(例: PATH=/usr/bin:/bin)であり、ユーザーが独自にインストールしたコマンドやNode.js、Python、Dockerなどが見つからず「command not found」で失敗します。
解決策は2つあります。
方法A:コマンドをすべて「絶対パス」で記述する(推奨) 実行するコマンドのパスを「which コマンド名」で調べ、完全な絶対パスで指定します。
$ which python3
/usr/bin/python3
$ which docker
/usr/bin/docker
crontabの指定例:
0 2 * * * /usr/bin/python3 /home/ubuntu/scripts/main.py
方法B:crontabの先頭でPATHを明示的に定義する crontabファイルの冒頭にPATH変数を宣言しておくことで、ログイン時と同じようにコマンド名だけで呼び出せるようになります。
# crontabの冒頭に記述
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/ubuntu/.local/bin
# 以降は通常通り記述可能
0 2 * * * python3 /home/ubuntu/scripts/main.py
原因2:カレントディレクトリと相対パスの不一致
スクリプト内で設定ファイルや入出力ファイルを指定する際、「./config.json」や「data/input.csv」のような相対パスを使っていると高確率で失敗します。
cronジョブが実行される際のカレントディレクトリ(作業ディレクトリ)は、デフォルトで実行ユーザーのホームディレクトリ(例: /home/ubuntu)になります。そのため、スクリプトがあるディレクトリとは異なる場所を基準にファイルを探してしまい、「No such file or directory」というエラーが発生します。
解決策は次のいずれかです。
方法A:crontab内で実行ディレクトリに移動してからスクリプトを実行する 「cd」コマンドで対象のプロジェクトディレクトリに移動した上でコマンドを連結実行(&&)します。
0 2 * * * cd /home/ubuntu/myapp && ./run_batch.sh >> /home/ubuntu/myapp/log/batch.log 2>&1
方法B:スクリプト側で自身のディレクトリを基準にする シェルスクリプトの先頭に以下を記載し、どこから実行されても自動的にスクリプトが存在するディレクトリに移動するように記述しておきます。
#!/bin/bash
cd "$(dirname "$0")" || exit 1
# ここからメイン処理
python3 main.py
原因3:ファイルの実行権限と実行ユーザーの不一致
作成したシェルスクリプトやプログラムに実行権限が付与されていない場合、cronは起動できません。
手動実行時に「bash script.sh」や「python3 script.py」と実行していた場合は動きますが、crontabに「/path/to/script.sh」と直接指定した場合は「Permission denied」エラーになります。
解決策: 以下のコマンドで対象ファイルに実行権限(実行ビット)を付与します。
chmod +x /home/ubuntu/scripts/backup.sh
また、管理者権限(root権限)が必要な処理(systemctlの再起動や特定のシステムファイル書き込みなど)を一般ユーザーのcrontabに登録していないかも確認してください。root権限が必要な処理は、一般ユーザーではなく「sudo crontab -e」で登録するか、「/etc/crontab」に設定する必要があります。
原因4:cronデーモンのログ確認と動作検証手順
「そもそもcronデーモン自体が動いているのか」「ジョブがキックされたのか」を調査するには、システムのログを確認するのが最も確実です。
Ubuntu 26.04 / 24.04 LTSなどのsystemd環境では、journalctlコマンドを使ってcronデーモンのログを確認できます。
# cron関連の最新ログを50行表示
sudo journalctl -u cron -n 50
# cronログをリアルタイムで追跡監視(動作テスト時に便利)
sudo journalctl -f -u cron
CentOSやAlmaLinuxなどのRHEL系ディストリビューションでは、/var/log/cron ファイルに記録されます。
sudo tail -n 50 /var/log/cron
ログの中に以下のようなレコードが出力されていれば、cronデーモンが指定時刻にジョブを呼び出したことが確認できます。
CMD (/home/ubuntu/scripts/backup.sh >> /var/log/backup.log 2>&1)
注意点として、システムログ(journalctlや/var/log/cron)は「cronがコマンドを起動した事実」のみを記録し、スクリプトの内部で発生したエラー(Pythonの例外やSQLエラー等)までは記録されません。内部エラーを追跡するためには、前述の「>> /path/to/log.log 2>&1」でスクリプトの標準エラー出力を個別のログファイルに記録することが不可欠です。
確実に動くかを検証したい場合は、まず「毎分実行」で日時を出力するテストジョブを登録し、ログが出力されるか確認するのが安全です。
# 疎通テスト用(動作確認後に削除する)
* * * * * date >> /tmp/cron_test.log 2>&1
まとめ
cronおよびcrontabは、Linuxでルーチン作業を自動化し、安定したサーバー運用を実現するための基本かつ最重要のツールです。
- crontabの基本構文は「分 時 日 月 曜日 コマンド」の順に指定する
- 毎時は「0 * * * *」、毎日深夜2時は「0 2 * * 」、5分ごとは「/5 * * * *」と指定する
- 編集は「
crontab -e」、確認は「crontab -l」を使用し、「crontab -r」の全消去事故を避けるために編集前のバックアップを徹底する - メール通知の不要な肥大化を防ぐために「MAILTO=””」を設定し、ログは「>> /path/to/log 2>&1」で追記保存する
- 動かないときは「PATHの違い(絶対パス化)」「カレントディレクトリの違い(cd)」「実行権限(chmod +x)」「
journalctl -u cron」の4点を確認する
基本ルールと注意点をしっかり押さえて、日々のサーバー運用やデータ処理を安全に自動化していきましょう。
次に読むおすすめ記事
UbuntuやLinuxの全体像、初期設定、基本コマンド、SSHやSambaのサーバー構築手順を体系的に学びたい方は、以下の完全ガイドもあわせて参考にしてください。


