はじめに
cronは、指定した時間や間隔で自動的にコマンドやスクリプトを実行するためのUnix系システムのデーモンです。定期的なタスクの自動化には非常に便利で、サーバーのメンテナンスや定期的なデータバックアップなどに使用されます。この記事では、cronとその設定ファイルであるcrontabの基本的な使い方について解説し、いくつかの便利なテクニックも紹介します。
cronとは?
cronはUnix系OSの標準機能として提供されているタスクスケジューラーです。指定した日時に定期的にコマンドを実行することができます。cronを利用するためには、crontab
という設定ファイルを編集して、どのタイミングでどのコマンドを実行するかを指定します。
crontabとは?
crontab
は、cronで実行するタスク(ジョブ)を設定するためのファイルです。このファイルには、実行するコマンドとその実行タイミングを記述します。各ユーザーが自身のcrontabファイルを持つことができ、ユーザーごとに異なるタスクを設定することが可能です。
crontabの基本書式
crontab
の各行には、以下の形式で実行するコマンドとそのスケジュールを指定します。
分 時 日 月 曜日 コマンド
各フィールドの意味は次のとおりです:
- 分: コマンドを実行する分(0 - 59)
- 時: コマンドを実行する時間(0 - 23)
- 日: コマンドを実行する日(1 - 31)
- 月: コマンドを実行する月(1 - 12)
- 曜日: コマンドを実行する曜日(0 - 7、日曜日は0または7)
例えば、毎日午後1時にスクリプト/home/user/script.sh
を実行したい場合、crontabに以下のように記述します。
0 13 * * * /home/user/script.sh
特殊な文字の使い方
crontabでは、以下の特殊な文字を使用して柔軟なスケジュール設定が可能です。
-
*
: すべての値を指定する(例:毎分、毎時など) -
,
: リストを指定する(例:1,2,3
は1分、2分、3分に実行) -
-
: 範囲を指定する(例:1-5
は1から5まで) -
/
: 間隔を指定する(例:*/5
は5分毎に実行)
例:月曜から金曜の毎朝9時に/home/user/backup.sh
を実行する場合は、次のように設定します。
0 9 * * 1-5 /home/user/backup.sh
crontabの管理コマンド
以下のコマンドを使用して、crontabの内容を編集・確認・削除できます。
- crontab -e : 現在のユーザーのcrontabを編集します。
- crontab -l : 現在のユーザーのcrontabの内容を表示します。
- crontab -r : 現在のユーザーのcrontabを削除します。
cronテクニック
crontab -e で直接編集しない
有名な話ですが、crontab -r
とやってしまうと全てが一瞬で消え去ります。crontab -e
とcrontab -r
は隣同士にあるため、編集と削除のコマンドを間違えて実行してしまうことがあります。これを防ぐために、crontab -e
を使用して直接編集するのではなく、ローカルファイルに設定を書いてからそれを反映させる方法をお勧めします。
以下の手順で設定を行いましょう:
$ crontab -l > ~/crontab # 現在の設定をバックアップ
$ vi ~/crontab # ローカルファイルを編集
$ crontab < ~/crontab # ローカルファイルを反映する
この方法を使用すると、間違えてcrontabを削除してしまうリスクを減らすことができます。
crontab設定をバージョン管理する
crontab設定をGitなどのバージョン管理システムで管理することを強くお勧めします。これにより、誰がいつどのように設定を変更したのかを追跡することができ、トラブル発生時に直近の変更内容を簡単に確認できます。
MAILTOを必ず設定する
cronジョブの出力を受け取るメールアドレスを設定しないと、サーバー内のユーザーのローカルのメールボックスにメールが届いてしまいます。これでは管理が不便ですので、アラート受信用の専用のメールアカウント(例:会社や部署のメーリングリスト)を用意し、crontab
の冒頭でMAILTO
を設定しておきましょう。
MAILTO="メールアドレス"
標準出力は捨てない (> /dev/null してはダメ)
cronジョブのログは非常に重要です。command > /dev/null
などで標準出力を捨ててしまうと、トラブルシューティングの際に情報が得られなくなります。ログは必ずファイルに出力するようにし、以下のように専用のログファイルに追記しましょう。
command >> /path/to/logfile
ログファイルが肥大化しないように、別途ログローテーションの仕組みを作っておくことも大切です。
エラーメッセージは標準エラー出力に吐く
スクリプト内でエラーが発生した際のエラーメッセージは、標準エラー出力に出力するようにしましょう。標準出力にエラーメッセージを出力してしまうと、エラーと正常なメッセージの区別がつきません。良い例として、以下のようにします。
echo "error message" 1>&2
または
echo "error message" > /dev/stderr
コマンド重複をまとめる
同じスクリプトを複数回実行する場合、例えば朝と夕に1日2回実行する場合など、2行に分けて記述するのではなく、1行にまとめて記述しましょう。
悪い例:
0 11 * * * /bin/bash /home/user/bin/script.sh
0 17 * * * /bin/bash /home/user/bin/script.sh
良い例:
0 11,17 * * * /bin/bash /home/user/bin/script.sh
パス名の重複をまとめる
スクリプトの実行パスやログの保存先など、繰り返し使用するパス名は環境変数を使ってまとめると、スクリプトがすっきりし、メンテナンスが楽になります。
悪い例:
0 9 * * * /bin/bash /home/user/bin/script1.sh >> /home/user/logs/script1.log
0 10 * * * /bin/bash /home/user/bin/script2.sh >> /home/user/logs/script2.log
良い例:
BIN_DIR="/home/user/bin"
LOG_DIR="/home/user/logs"
0 9 * * * /bin/bash $BIN_DIR/script1.sh >> $LOG_DIR/script1.log
0 10 * * * /bin/bash $BIN_DIR/script2.sh >> $LOG_DIR/script2.log
実行時間を0分きっかりにしない
多くのcronジョブが同じ0分に実行されると、サーバーに過負荷がかかる可能性があります。できるだけ実行時間を微妙にずらすことで、負荷の分散を図りましょう。
悪い例:
0 * * * * /bin/bash $BIN
_DIR/script1.sh >> $LOG_DIR/script1.log
30 * * * * /bin/bash $BIN_DIR/script2.sh >> $LOG_DIR/script2.log
良い例:
3 * * * * /bin/bash $BIN_DIR/script1.sh >> $LOG_DIR/script1.log
33 * * * * /bin/bash $BIN_DIR/script2.sh >> $LOG_DIR/script2.log
定期的な監視とログ確認
cronの設定は一度作ったら終わりではありません。定期的にジョブの実行状況を確認し、ログをチェックしてエラーがないか確認しましょう。特にcronジョブが多い場合は、専用の監視ツールを導入することも考慮に入れると良いでしょう。
以上がcronとcrontabの基本的な使い方といくつかのテクニックの紹介です。皆さんの環境でcronをうまく活用して、日々の運用をより効率的にしてください。