cronについて
時間ベースのジョブスケジューラです。スクリプトやコマンドを定期的・自動的に実行するために使います。
モダンなサーバー運用ではcronを避ける傾向があります(拡張性が低いため)。代替として systemd timer があり、次のセクションで紹介します。しかし、現場ではまだまだcronが多く使われているため、使い方を押さえておきましょう。
本研修で使用するAmazon Linux 2023のサーバーでは、デフォルトではcrontabが使えません。cronieパッケージをインストールします:
sudo yum install cronie -y crondサービスを起動します:
sudo systemctl start crond.service crontabコマンド
現在のユーザーのcronジョブを一覧・編集するコマンドです。
-
crontab -e… 自分のcrontabを編集する -
crontab -l… 現在の設定を表示する -
crontab -r… 全てのcron設定を削除する
crontab -r は全てのcron設定を確認なしに一発で削除します! -e(編集)のすぐ隣のキーなので、押し間違い事故が頻発します。
もし本番サーバーで誤って実行してしまうと:
- 定期バックアップが停止 → 障害時にデータ復旧できなくなる
- ログローテーションが止まる → ディスクが溢れてサービスダウン
- 定期的な証明書更新が止まる → SSL証明書が期限切れでサイトにアクセスできなくなる
- バッチ処理(集計・通知・同期など)が全て停止 → 気づくまで数日かかることも
対策: 設定変更前に crontab -l > ~/crontab_backup_$(date +%Y%m%d).txt でバックアップを取る習慣をつけましょう。
Amazon Linux 2023ではエディタは環境変数 EDITOR で決まります。vimを使いたい場合は事前に以下を実行してください:
export EDITOR=vim cronの実行環境に関する注意(重要)
cronジョブはログインシェルとは異なり、.bashrc や .bash_profile が読み込まれません。そのため PATH が極めて限定的(/usr/bin:/bin 程度)になります。
よくあるハマりパターン:
# ターミナルでは動くのにcronでは動かない!
* * * * * python3 /home/ec2-user/script.py
# → cronだとpython3のパスが通っていない 対策:
- コマンドはフルパスで記述する(例:
/usr/bin/python3) - またはスクリプト冒頭で
PATHを明示的に設定する
cronの設定方法
5つのフィールド(分 時 日 月 曜日)をスペースで区切り、その後に実行コマンドを記述します:
* * * * * command
| | | | |
| | | | +---- 曜日 (0-7, 0と7は日曜日)
| | | +------ 月 (1-12)
| | +-------- 日 (1-31)
| +---------- 時 (0-23)
+------------ 分 (0-59) 例:毎週火曜日の8:30にスクリプトを実行する
30 8 * * 2 /bin/bash /home/ec2-user/example1.sh 範囲指定・複数指定も可能:
# 月〜金の17:15に実行
15 17 * * 1-5 /bin/bash /home/ec2-user/example1.sh
# 毎月10日と20日の2:00に実行
0 2 10,20 * * /bin/bash /home/ec2-user/example1.sh 出力のリダイレクトについて:
cronジョブの標準出力・標準エラー出力を適切に処理しないと、メールが溜まったりログが肥大化します。出力が不要な場合は /dev/null にリダイレクトしましょう:
* * * * * /bin/bash /home/ec2-user/example1.sh > /dev/null 2>&1 ログとして残したい場合はファイルにリダイレクト:
* * * * * /bin/bash /home/ec2-user/example1.sh >> /home/ec2-user/cron.log 2>&1 crontabの保存場所
Amazon Linux(RHEL系)では、ユーザーごとのcrontabは以下に保存されます:
/var/spool/cron/ユーザー名 crontab -e を使いましょう。 crontab -e はファイルを正しいパーミッション(600)・正しい所有者で保存してくれます。vim 等で直接編集するとパーミッションや所有者が変わってしまい、crondがファイルを認識できず エラーも出さずに静かに動かなくなります。 「設定は正しいのに動かない」ときは ls -la /var/spool/cron/ で権限を確認してみましょう。 /etc/crontab について
システム全体のcronジョブは /etc/crontab に記述します(root権限が必要)。
ユーザー用crontabとの違いは、コマンドの前にユーザー名を指定する点です:
* * * * * ユーザー名 command
| | | | |
| | | | +---- 曜日 (0-7, 0と7は日曜日)
| | | +------ 月 (1-12)
| | +-------- 日 (1-31)
| +---------- 時 (0-23)
+------------ 分 (0-59) また、定期実行用のディレクトリが用意されています:
-
/etc/cron.hourly… 毎時実行 -
/etc/cron.daily… 毎日実行 -
/etc/cron.weekly… 毎週実行 -
/etc/cron.monthly… 毎月実行
これらのディレクトリにシェルスクリプトを配置するだけで、自動的に定期実行されます。
これは /etc/crontab 内に、これらのディレクトリを実行する指示が記述されているためです。
# /etc/crontab 内の一般的な記述例(Ubuntu/Debian系など)
17 * * * * root run-parts /etc/cron.hourly
25 6 * * * root run-parts /etc/cron.daily
47 6 * * 0 root run-parts /etc/cron.weekly
52 6 1 * * root run-parts /etc/cron.monthly ※ Amazon Linux 2023ではこの記述はなく、anacronが /etc/cron.hourly/0anacron 経由で daily/weekly/monthly の実行を管理しています。
/etc/crontab の内容はディストリビューション(Ubuntu、CentOS、Amazon Linuxなど)ごとに異なります。ネット上の記事や教科書の例がそのまま当てはまるとは限らないので、実際のサーバーで cat /etc/crontab を実行して中身を確認してみましょう。 cronのログ確認
cronジョブが正しく動いているか確認するには、journalctlを使います:
# crondのログをリアルタイムで確認
sudo journalctl -f -u crond
# crondの過去のログを確認
sudo journalctl -u crond 余裕がある人向け:トラブルシューティング演習
問題:以下のcrontab設定は正しく動作しません。なぜでしょう?
* * * * * echo "genki 100% desu!!" >> /home/ec2-user/hoge.txt ヒント:
-
sudo journalctl -f -u crondでログを確認してみましょう - コマンドの実行が
echo "genki 100で止まっています
答え:
cronでは % 文字がコマンドの終端(改行)として解釈されます。\(バックスラッシュ)でエスケープする必要があります:
* * * * * echo "genki 100\% desu!!" >> /home/ec2-user/hoge.txt