面倒なルーチンワークはcronにお任せ
cronとは定期的にコマンドやスクリプトを自動実行するための機能です。
定期的なバックアップ、データベースの最適化、ウイルススキャンの実行など、人の手で行うのが億劫な処理を一手に引き受けてくれる、ありがたい存在です。
cronの動作確認
crondというプロセスで実行されます。通常はLinuxの起動と同時に実行されています。
crondの実行プロセスを確認
# service crond status
crondの起動
もし起動していない場合は以下のコマンドで起動しておいてください。
# service crond start
cronの自動起動の確認
3番がONになっているか調べます。
# chkconfig --list crond
cronの自動起動の有効にする
もし有効になっていない場合は以下のコマンドで自動起動を有効にします。
# chkconfig crond on
cronの設定と書式
cronの設定ファイルは「/etc/crontab」です。それでは設定ファイルを開いて、書式を確認しましょう。
(下の例はCentOS 5系の場合です。CentOS 6系では定期実行は「/etc/anacrontab」にまとめられています)
# vi /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
上から順番に見ていきます。
1~2行目、まずSHELLとPATHでコマンドへパスを通しています。
3行目、MAILTO=rootで実行結果をroot宛にメールするという設定になっています。
メールが届かないようにするには「MAILTO=””」とダブルクォーテーションを2つ付けます。※エラー等が起こった場合の出力も送信されるので、容量が許せば受け取って置くことをお勧めします。
rootだと受け取れる人が限られているので、cron専用のユーザーを作って、管理者全員にエイリアスで送信するというのもお勧めです。
※MAILTO自体を削除してもcrond実行ユーザーへメールを送信します。(デフォルトではroot)
4行目、「HOME=/」crondがスクリプトを実行する際のディレクトリを指定します。
その後に続く「# run-parts」から下が実際に定時に実行されるプログラムの設定になります。
その後にスペース区切りで数字やディレクトリ等が指定されています。
詳しくは後述するとして、数字の後の「root」はrootユーザの権限で実行するという設定。
「run-parts <ディレクトリ>」はディレクトリを指定する際に記述します。
run-partsの特殊な制約について run-partsには以下のルールが存在します。
- 実行はアルファベット順
- サブディレクトリは無視
- option
- -aで引数を指定すると、各スクリプトに共通の引数が渡せる
- -v verbose
- ファイル名に一部制限あり
- debian「.(ドット)」を含むファイルは使えない。
- redhat「~(チルダ)か,(カンマ)」で終わるファイルは使えない。
設定にあるそれぞれのフィールドについて
それぞれのフィールドは左から順番に以下のような意味になっています。
各フィールドと入力する値
フィールド | 指定する値 |
---|---|
分 | 0~59 |
時 | 0~23 |
日 | 1~31 |
月 | 1~12 もしくは jan~dec |
曜日 | 0~7 (0と7は日曜日) もしくは sun~sat |
コマンド | 有効なコマンド(ディレクトリまたはシュルスクリプトファイル)を記述します。 |
「*(アスタリスク)」はどんな意味かというと、それぞれのフィールドが1増加するごとに実行するという指定になります。
少し分かりにくいので実例で解説します。
設定ファイルの一番上の例では分フィールドに01が指定され、後は*です。
*の意味を省略せずに書くと「毎月・毎曜日・毎日・毎時、分数が1の時に実行」という意味になります。
01 * * * *
例えば月曜日だけ毎時実行したいという場合は週フィールドに1を指定します。
01 * * * 1
cronの便利な指定方法
cronでは複雑な指定もできるように便利な設定方法が用意されています。
複数の時間で実行する
毎時1分と30分の2回実行したい場合、「,(カンマ)」で区切ることで複数の時間を指定できます。
01,30 * * * *
連続した時間の範囲で実行する
毎時1分から10分まで毎分連続して実行したい場合は「-(ハイフン)」で指定します。
01-10 * * * *
一定の間隔で実行する
6分毎に規則的な期間で実行するには「/(スラッシュ)」を使います。
*/6 * * * *
応用として、ハイフンとスラッシュを組み合わせれば1分から20分まで6分ごとに実行ということもできます。
01-20/6 * * * *
crontabによる新しいルールの作成
rootユーザーでcronの設定ファイルを作成する場合は「/etc/crontab」を編集していましたが、crontabというコマンドを使えば、一般ユーザーでも個別にcronの設定ファイルを作成することができます。
書式
crontab [ -u ユーザ名 ] { -l | -r | -e }
新しいルールの作成
hogeユーザー用の新しいルールを作成する。
# crontab -r hoge -e
するとエディタが立ち上がるのでviと同じ要領で編集します。
MAILTO=hoge 0-59 * * * * echo "hoge"
ユーザーの指定に使う「-r hoge」を省略すると、現在実行しているユーザーのルールが追加されます。
無事終了すると以下のように表示されます。
crontab: installing new crontab
上記の設定だと、hogeユーザー宛に、Cron Demonから「hoge」と書かれたメールが毎分届きます。
ユーザー個別の設定ファイルは「/var/spool/cron/」にユーザー名ごとに作成されます。
ルールの確認
# crontab -l
ルールがない場合は以下のように表示される。
no crontab for hoge
ルールの削除
こちらのコマンドは確認もせずに全てのルールを削除するので、使用はお薦めできません。「crontab -e」で開いて、必要のなくなったルールだけ削除すると事故が減ります。
# crontab -r
cronを利用する上でのテクニック
cronを利用する上で知っておくと便利なちょっとしたテクニックを紹介します。
メールを送信するスクリプトを限定する
新規ルールを追加
# crontab -e
以下を追加します。
MAILTO="" 0-59 * * * * echo "hoge" 0-59 * * * * echo "huga" 2>&1 | Mail hoge@example.com
「MAILTO=””」となっているのでメールは送信さませんが、「|(パイプ)」でつないで「Mail hoge@example.com」と渡しているので「huga」というスクリプトの実行結果だけ送信されてきます。
tちなみに「2>&1」はお決まりの、標準出力と標準エラーを合わせて出力するという指定です。
この形式の場合、メールの差出人はcronではなく、実行したユーザーとドメイン名「hoge@example.com」で送信されてきます。
出力をログファイルに書き出す
頻繁に実行されるスクリプトがあるとメールの数が多くなります。そうなるとメール送信を停止したくなります。
しかしそれではエラーが出た際に状況を把握できなくなります。そこで一般のソフトと同じようにログファイルを作成して結果を出力するようにするとメールがcronの結果で一杯になることを防げます。
まずはrootユーザーでログファイルを作ります。(通常/var/logはrootユーザーしか変更できないため)
# echo -n > /var/log/www_cronlog
実行権限の設定(一般ユーザーで作成したcronは一般ユーザーの権限で実行されるため。もちろんrootユーザーでルールをさくせする場合は必要ありません。)
# chmod 646 /var/log/www_cronlog
# crontab -e (以下を追加) MAILTO="" 0-59 * * * * echo "hoge" 2>&1 >>/var/log/www_cronlog
これでメールを飛ばさない代わりに、ログファイル「/var/log/www_cronlog」に結果が出力されます。
追記を行うためのリダイレクション記号は「>」が2つです。1つだと書き出すごとに上書きされてしまうので過去のログを参照できません。
また、ログファイルが肥大化しないようにrsyslog等でログローテートしてください。ログローテートの方法は「以前の投稿」をご覧ください。
cronの実行時間を0分きっかりにしない
「cron力をつけよう!全てのcrontab入門者に贈る9個のテクニック」より
(RHEL6系以降は「/etc/anacrontab」があるためこのような設定は不要)
cronを実行する際に同じ時間で実行されるスクリプトが重なるとサーバが重くなってしまいます。
そこで◯時きっかりというcronで設定しがちな時間から、わざとずらすのが効果的です。
悪い例
0 * * * * echo "hoge"
良い例
5 * * * * echo "hoge" 35 * * * * echo "hoge"
また、cronのデフォルトで設定されている時間もずらすのがお勧めです。
デフォルトの設定は下記の表記から分かるように毎時1分、毎日4時2分、毎週4時22分、毎月1日の4時42分となっています。
cronのデフォルトの設定
01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly
特にウイルススキャンやデータベースの最適化など重い処理を行う場合はこの時間からずらしておきましょう。
複数の管理者がいる場合は時間をずらしていることを通知するのを忘れずに。
もちろん一番良いのはSysstat等でサーバのピークタイムを算出して、その時間を避ける事です。
ピンバック: cronな話 | Barbarossa Blog