Linuxで定期的に処理を実行させる方法(cron, anacron)

Linuxで定期的に処理を実行させる方法(cron, anacron)

Linuxで、指定した処理(ジョブ)を定期的に実行させたいときには、cronやanacron、systemd-timerを使った方法がありますが、設定の分かりやすさではcronやanacronを使った方法が分かりやすいです。

そこでここでは、RedHat互換のLinuxでcronやanacronでジョブを設定する方法を解説します。

cronとanacronの違い

cronとanacronの一番の違いは、実行タイミングで、cronでは指定した日時ピッタリに実行されますが、anacronでは、指定した実行可能範囲の間で実行され、いつ実行されるかは大まかな範囲でしか分かりません。

そのほかの違いは以下のとおりです。

cronの特徴

  • 「etc/crontab」「/etc/cron.d/以下のファイル」「各ユーザのcrontabファイル」など、複数のジョブを設定するためのファイルがある
  • デーモンプロセス(crond)が常駐して指定日時に設定したジョプが起動される
  • 曜日・時・分・秒の粒度で、ジョブを実行できる
  • ジョブの実行時刻にLinuxが停止していた場合に、ジョブを再実行する機能はない(次回の実行日時まで待つ必要がある)

anacronの特徴

  • ジョブの設定ファイルは「/etc/anacrontab」のみで、rootユーザー以外はジョブの設定ができない
  • 現在のLinuxでは、デフォルトで/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthlyのそれぞれのディレクトリに配置したスクリプトは、anacronで実行されるよう設定されている
  • anacronにはデーモンプロセスが存在しないため、cronからanacronコマンドが定期的に呼び出されている(設定は、/etc/cron.hourlyディレクトリ配下の0anacronファイルに記述されている)
  • ジョブの実行間隔は、最小で1日単位までで1日1回以上の実行頻度は指定できず、ジョブの実行時刻を明示的に指定することもできない
  • ジョブの実行時刻にLinuxが停止していた場合は、次回Linuxが起動したときに自動的に実行される

cronでジョブを設定する方法

cronでジョブを実行させるための設定ファイルは、以下の3つがありますが、自分しか使用しないマシンなら「/etc/crontab」ファイルに記述する方法がシンプルでおすすめです。

  • /etc/crontab - システム全体に適用したいジョブを作成
  • /etc/cron.d/以下のファイル - システム全体に適用したいジョブを用途ごとなどで設定ファイを分けて記述したいときは、このディレクトリ配下に設定ファイルを作成します。(RedHatでは、/etc/crontabに直接記述する方法よりも、/etc/cron.d/以下にファイルを作成する方法が推奨されています。)
  • crontabコマンドで設定するファイル「/var/spool/cron/crontabs」 - ユーザーごとのジョブを作成

新規ジョブの登録方法

ここからは「/etc/crontab」にジョブを登録するときの記述方法を紹介します。

「/etc/crontab」にジョブを登録するときは、viなどのテキストエディターで開いて編集します。

# vi /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# 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
* * * * * nginx /usr/bin/php -q /usr/share/nginx/servermemo/wordpress/wp-cron.php >/dev/null

「/etc/crontab」ファイルの上3行は、環境変数の設定部分です。「MAILTO」を設定するとcronの標準出⼒・標準エラー出力を、指定の宛先へメールで送ることができます。

書式

新たなジョブを登録する際は、最終行に以下のような書式で追記します。

* * * * * nginx /usr/bin/php -q /usr/share/nginx/servermemo/wordpress/wp-cron.php >/dev/null

書式:[分] [時] [⽇] [⽉] [曜⽇] [ユーザー名][コマンド]

設定項目 説明
0~59の数字で指定します。
0~23の数字で指定します。
1~31の数字で指定します。
1~12の数字で指定します。
曜日数字で指定します。0と7が日曜日で1以降は順に月~土となります。
ユーザー名コマンドを実行するユーザーを指定します。
コマンドフルパスで指定します。

ちなみに、crontabコマンドを使ってユーザーごとのジョブを登録するときは「分 時 日 月 曜日 コマンド」という書式で記述します。

実行周期の記述例

実行周期の記述方法は、いろいろあるので以下を参考にしてみてください。

記述 説明
* * * * *毎分実行
0 * * * *毎時0分に実行
*/10 * * * *10分おきに実行
0 12 * * *毎日12:00に実行
45 23 * * *毎日23:45に実行
30 8 * * *毎日8:30に実行
* 1 * * *毎日1:00から1:59まで1分おきに実行
5 9-21/3 * * *毎日9:05,12:05,15:05,18:05,21:05に実行
0 17 * * 1毎週月曜の17:00に実行
0,30 15 * * 0,2,3毎週日,火,水曜の15:00と15:30に実行
0 21 * * 1-6毎週月曜日から土曜まで21:00に実行
0 13 1 * *毎月1日の13:00に実行
30 5 1,15 * *毎月1日と15日の5:30に実行
0-10 17 1 * *毎月1日の17:00から17:10まで1分おきに実行

anacronでジョブを設定する方法

anacronの設定ファイル「/etc/anacrontab」には、デフォルトでetc/cron.dailyディレクトリに配置したスクリプトが日次で実行、/etc/cron.weeklyに配置したスクリプトが週次で実行、/etc/cron.monthlyディレクトリに配置したスクリプトが月次で実行されるように設定されています。

#vi /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

新規ジョブの登録方法

「/etc/anacrontab」ファイルにジョブを追加設定することもできます。たとえば、シェルスクリプト「/usr/local/bin/my-script.sh」を3日に1回実行し、実行遅延は60分で設定したいときは、以下のように記述します。

#period in days   delay in minutes   job-identifier   command
3       60       cron.daily              /usr/local/bin/my-script.sh

日次・週次・月次ジョブをcronで実行するには

/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthlyディレクトリ配下にあるスクリプトは、デフォルトでは、anacronで実行されるように設定されていますが、cronで指定した日時ピッタリに実行させたいときは、「cronie-noanacron」をインストールし、その後「cronie-anacron」を削除します。

# dnf -y install cronie-noanacron
# dnf -y remove cronie-anacron

ジョブの動作確認

登録したジョブの実行結果は、ログファイル「/var/log/cron」に記録されるので、新しいジョブを登録したら、指定した周期でジョブが実行されているかログを確認しましょう。

ジョブの実行結果メールをカスタマイズ(おまけ)

cronやanacronでは、デフォルトでジョブに設定したスクリプトなどの標準出⼒・標準エラー出力がroot宛へメール送信されますが、デフォルトの通知メールではメールの本文を確認しないと状況がよくわからず使いづらく感じるときがあります。

そのようなときは、以下のようにmailコマンドとスクリプトを組み合わせたコマンドをジョブとして実行させることで、メールの件名だけでジョブの実行結果を判断できるようにできます。

# MSG=`/home/hoge/scripts/myscript.sh`; (if [ -n "$MSG" ]; then (echo $MSG | mail -s 'NOTICE : Something went wrong.' [email protected]) fi)

上のコマンドの処理の流れは、以下のとおりです。

MSG=`/home/hoge/scripts/myscript.sh`

スクリプト「myscript.sh」の戻り値を、変数「MSG」に代入しています。

if [ -n "$MSG" ]; then

変数「MSG」の文字列長が0より大きい場合に、指定した処理(メール送信)を行います。なお、if文での条件判定は、実行するスクリプトが返す値によって適宜修正してください。

echo $MSG | mail -s 'NOTICE : Something went wrong.' [email protected]

以下の内容でメールを送信します。

  • 件名:NOTICE : Something went wrong.
  • 宛先:[email protected]
  • 本文:変数MSGの内容

cronから日に何通もメールが来るのであれば、ここで紹介したような方法でメールの件名などを分かりやすくカスタマイズすればば、いちいち本文を見なくても件名を見ただけで状況を把握できて便利です。