cronについて(on CentOS)



●ランダム化について

 CentOS6のcron.daily等の実行時刻は、CentOS 5以前とは異なってます。
 CentOS 5以前であれば、デフォルトでは午前4:02にスケジュールされていましたが、CentOS 6のデフォルトでは、ある幅の範囲内でランダム化されています。
 まずは、このランダム化の内容を確認してみます。
 /etc/crontabの内容を確認します。
# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
 CentOS 5以前であれば、次のようにエントリーされていました。
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
 ランダム化は、anacron (cronie-anacron) により行われており、設定内容は /etc/anacrontab に記述されています。デフォルトの /etc/anacrontab は、次のとおりです。
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days   delay in minutes   job-identifier   command
1	5	cron.daily		nice run-parts /etc/cron.daily
7	25	cron.weekly		nice run-parts /etc/cron.weekly
@monthly 45	cron.monthly		nice run-parts /etc/cron.monthly
 いくつかのパラメータがあり、man anacrontab(5)に解説がありますが、概説しますと、赤字の1(左端) が実行周期(日時実行=1)で、次の数字5は、実行開始タイミングになってから、5分間の遅延を入れる指定です。実行開始する時間帯はSTART_HOURS_RANGEで制御され、3-22とは、3時から22時までの範囲 (3:00 ≦ t < 22:00) を指定しています。ランダム化の幅はRANDOM_DELAYで制御され、45とは0~45分の範囲(乱数計算の実装上、正確には44分まで)でランダムに遅延を行うことを指定しています。
 やや複雑ですが、このデフォルト設定で24時間運用した場合、cron.dailyは午前3:06から3:50の間でランダム実行されることになります。ここで 3:06なのは、そもそもanacron が動作する周期が毎時01分であるためです。/etc/cron.d/0hourlyおよび/etc/cron.hourly/0anacron参照。
 また、もし毎日シャットダウン電源OFF運用を行う場合、例えば、午前6:00にブートすると、その直後の午前6:06から6:50の間でランダムにcron.dailyが実行されることになります。
 もしも、1日以上シャットダウンしていて、午後23:00にブートした場合には、START_HOURS_RANGEの範囲外であるため、cron.dailyの実行は、翌日の午前3:06から3:50の間ということになります。
 このランダム化は、仮想化環境を考慮してのこと(ゲストOSのcron.dailyが重ならないようにする意図)とは思いますが、ランダムに動作されるのは運用上よろしくない(混乱要因となる)と考える方も居るかと思います。CentOS 6では、CentOS 5以前のように固定の時刻にcron.dailyを行わせるようにする方法も用意されており、デフォルトでインストールされるcronie-anacronパッケージの代わりに、cronie-noanacronをインストールすればよいです。

●CentOS 6のcron.daily実行時刻をCentOS 5以前と同様に設定するには

 パッケージの依存関係のため、事前にcronie-noanacronをインストールし、その後にcronie-anacronを削除するという手順を踏みます。
 # yum install cronie-noanacron
...途中省略...
Installed:
  cronie-noanacron.x86_64 0:1.4.4-7.el6
Complete!
# rpm -e cronie-anacron
 このcronie-noanacronは、ちっぽけなパッケージで、/etc/cron.d/dailyjobsファイルだけを含んでいます。
# rpm -qi cronie-noanacron                                                   
Name        : cronie-noanacron             Relocations: (not relocatable)
Version     : 1.4.4                             Vendor: CentOS
Release     : 7.el6                         Build Date: Tue 19 Jul 2011 01:55:56 PM JST
Install Date: Thu 17 Jan 2013 12:02:39 AM JST      Build Host: c6b5.bsys.dev.centos.org
Group       : System Environment/Base       Source RPM: cronie-1.4.4-7.el6.src.rpm
Size        : 326                              License: MIT and BSD and ISC and GPLv2
Signature   : RSA/SHA1, Mon 26 Sep 2011 01:17:22 PM JST, Key ID 0946fca2c105b9de
Packager    : CentOS BuildSystem 
URL         : https://fedorahosted.org/cronie
Summary     : Utility for running simple regular jobs in old cron style
Description :
Old style of {hourly,daily,weekly,monthly}.jobs without anacron. No features.
# rpm -ql cronie-noanacron
/etc/cron.d/dailyjobs ← パッケージの中身はこれ1個
 /etc/cron.d/dailyjobsの中身は次のようになっています。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
02 4 * * * root [ ! -f /etc/cron.hourly/0anacron ] && run-parts /etc/cron.daily
22 4 * * 0 root [ ! -f /etc/cron.hourly/0anacron ] && run-parts /etc/cron.weekly
42 4 1 * * root [ ! -f /etc/cron.hourly/0anacron ] && run-parts /etc/cron.monthly
 CentOS 5以前での運用経験があれば、見慣れた実行時刻かと思います。
 ただし、0anacronの存在チェックが行われており、cronie-anacronパッケージを削除しないと有効化されないようにガードされています。ご注意を。
 すでにお分かりかとは思いますが、cron.weeklyおよびcron.monthlyも同様です。
 ただ、cron.hourlyはランダム化されておらず、次のように etc/cron.d/0hourlyに設定が書かれています。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
01 * * * * root run-parts /etc/cron.hourly

●cronとは(CentOS 5まで)

 cronとは、決められた時刻にコマンドを定期的に実行させるためのデーモンプロセスです。
 cronではコマンドだけにとどまらず、シェルスクリプトや、PerlやPHPなどのインタープリタ言語で書かれたプログラムも動作させることができます。
 cronを実行させるためにはcrondが起動している必要があります。
# service crond status
crond (pid  5091) を実行中...
 crondが起動していない場合は下記コマンドで実行します。
# service crond start


●cronの設定ファイル(CentOS 5まで)

 cronの設定ファイルは /etc/crontab です。
# cat /etc/crontab
SHELL=/bin/bash ← /etc/passwordの記述に関係なく、強制的にここで定義されたシェルを使います。
PATH=/sbin:/bin:/usr/sbin:/usr/bin ← パスの設定です。ここに記述されたディレクトリ内の実行
                                        ファイルはパス名を省略して記述することが可能です。
MAILTO=root ← cronの実行結果をここで指定されたユーザー宛にメールで送ります。
                 ユーザ名を空にするとメールを送信しません。
                 ただし、MAILTOの記述自体をしないと、crontabファイルの所有者にメール
                 を送ります(デフォルトではroot)。
HOME=/ ← crondによりプログラム実行されるときの  カレントディレクトリの指定です。
# 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

●crontabコマンドでの登録

 cronを登録するにはcrontabコマンドに-eオプションをつけて実行します。
 “crontab -e”を実行するとエディタが起動してcronの設定ファイルが開きます。
 設定ファイルが開いたら、いつ、どのコマンドをどれぐらいの頻度で、何時何分に実行するかを記述していきます。
 記述のフォーマットは以下の通りです。
分 時 日 月 曜日 コマンド
 分は0~59の数字で指定、
 時は0~23の数字で指定、
 日は1~31の数字で指定、
 月は1~12の数字で指定、
 曜日に関しても数字で指定し、0と7が日曜日、1以降は順に、月、火、水、木、金、土となります。
 コマンドは、設定ファイルでパスを通していないものに関しては、フルパスで指定するかカレントディレクトリからの相対パスで指定しなければなりませんので、ご注意ください。
#  crontab -e
01 * * * * hourly.sh    ※毎時1分に"hourly.sh"コマンドを実行
0 3 * * * daily.sh    ※毎日3時ちょうどに"hourly.sh"コマンドを実行
30 4 * * 0 weekly.sh    ※毎週日曜日の4時30分に"weekly.sh"コマンドを実行
45 5 1 * * monthly.sh    ※毎月1日の5時45分に"weekly.sh"コマンドを実行
crontab: installing new crontab    ※保存して閉じるとcron登録が完了した旨のメッセージがでる
 このcrontabコマンドで編集したファイルは、/var/spool/cron ディレクトリにユーザ名をファイル名として保存されます。
# ls -l /var/spool/cron
-rw------- 1 root root 172  11月 18 16:34 root
 先の例ではrootでcrontabを実行したので、/var/spool/cronディレクトリにrootというファイルが作成されます。
 特定のユーザがcrontabを設定しているかどうかを知りたい場合は、この/var/spool/cronディレクトリを確認すればいいです。

●cron用ディレクトリにスクリプトを置いて実行する

 特定のディレクトリにコマンドを保存するだけで、cronとして登録することもできます。
 例えば、設定ファイルに”01 * * * * root run-parts /etc/cron.hourly”という記述があります。
 これは、”/etc/cron.hourly”ディレクトリに保存したコマンドは、毎時1分に実行されるという意味です。
 下記は主なcron用ディレクトリ一覧です。
 /etc/cron.hourly 1時間に1回実行
 /etc/cron.daily 1日に1回実行
 /etc/cron.weekly 1週間に1回実行
 /etc/cron.monthly 1ヶ月に1回実行

●現在登録されているcronを確認する

 現在登録されているcronの一覧を表示するには、下記コマンドを実行します。
#  crontab -l


●現在登録されているcronを削除する

 現在登録されているcronを削除するには、下記コマンドを実行します。
#  crontab -r
※`crontab -e`についてはこんな意見も。

"crontab" -r でいきなり削除しないようにする @LCD -Linux Command Dictionary-|Replog!株式会社レップワンスタッフによるブログです

crontab -e は「絶対に」使ってはいけない – ろば電子が詰まっている

 かいつまんで説明すると、`crontab -r`を実行すると何の警告もなくそのユーザの全てのcron設定が消えてしまう。`crontab -e`はこの危険な-rオプションとタイプミスをする可能性が高いので使うべきではない。

●cronが実行されないときの確認方法

 どうしても分からない場合は、ログを出力するように設定します。実行結果をファイルに出力することにより原因が特定できる場合があります。
* * * * * root /bin/perl /root/test.pl >>/tmp/exec.log 2>>/tmp/exec_error.log