server-memo.net

/etc/crontabと/etc/cron.d設定ファイルの書き方

      2016/01/22

/etc/crontabと/etc/cron.d/の書き方

/etc/crontabと/etc/cron.dの書き方メモです。

書式としては環境変数を設定し、実行するコマンド、シェルのスケジュールを記述という形になります。
参考としてCentOS 6.6の/etc/crontabの初期状態を見てみます。

「/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

環境変数設定部分と、コマンドのスケジュールの部分とに分かれていることが分かります。

設定ファイル内容

環境変数設定

変数の設定について説明します。
cronにはユーザの環境変数が引き継がれないため、ここで設定する必要があります。

SHELL

cronで使用されるシェルを設定します。

PATH

cronに教えるパスの設定します。
ここで設定されていないパス上にあるコマンド等を実行させる場合は、フルパスでコマンド等を設定する必要があります。

MAILTO

cronの実行結果を送るユーザまたはメールアドレスを指定します。
メールを送信したくない場合は「MAILTO=""」と設定します。

HOME

cronが実行されるカレントディレクトリとなります。

その他の環境変数

その他にも環境変数を設定したい場合は任意で設定することが可能です。
(変数名も任意で設定できます)

下記の例では、環境変数「COMMAND」に「logger cornd-test」を設定して、それをスケジュールで読み込んで実行しています。長いコマンドなどは、このように環境変数に設定することですっきりスケジュールを設定することができたりします。また、コマンドを編集する際にも変更もれがなくなったりと良いことがたくさんあります。

■コマンドを環境変数に設定した例

#!/bin/sh
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

COMMAND=logger cron.d-test

*/3 * * * * root $COMMAND
*/15 * * * * root $COMMAND
18 * * * * root $COMMAND

コマンドスケジュール設定

書式としては下記のとおりとなります。

分 時 日 月 曜日 実行ユーザ 実行コマンド

毎時15分に、「logger」コマンドで「/var/log/messages」にをログを書き出す設定の場合は下記のとおりとなります。

15 * * * * root logger crontab-test

スケジュールの詳しい設定方法はここのページにまとめてあるので、参考にしてみてください。

/etc/cron.dディレクトリ内のファイル書き方

「/etc/crontab」と同じ書式でかけば良いです。

注意をする点としては・・・

  1. パーミッションは644
  2. 所有者はrootで!

「/etc/cron.d/」ディレクトリ内の「0hourly」ファイルを確認してみると、「/etc/crontab」と同じ書式で書かれていることが分かります。

「/etc/cron.d/0hourly」ファイル
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
01 * * * * root run-parts /etc/cron.hourly

「/etc/crontab」同様に環境変数を設定し、その後に実行コマンドの設定を行っています。
ちなみ、設定内容は毎時01分にrootユーザが「/etc/cron.hourly」ディレクトリ内のプログラムを実行するという設定です。

「run-parts」がディレクトリ内のプログラムを実行するというコマンドになります。

cronが動かない場合

cronが動かない場合の切り分けとして下記の方法を試してみてください。

  • ログを確認
  • メールの確認
  • ファイルのパーミッション・所有者の確認
  • パスの確認
  • 改行コードの確認?
  • crondが動作しているか確認

ログを確認

/var/log/cronにログが出力されているので、確認してみましょう。何か解決へのヒントが記録されているかもしれません。

エラーメッセージ例

エラー各種です。

ファイルのパーミッションが違う場合

rootユーザ以外に実行権限や書き込み権限があったりすると実行されません。

■rootユーザ以外に実行権限がある場合

# ls -la /etc/cron.d/crontest
-rw-r-xr-x    1 root root   117  2月 24 00:18 2015 crontest

ログに「BAD FILE MODE」と表示されていました。

Feb 24 13:00:01 centos6 crond[7999]: (root) BAD FILE MODE (/etc/cron.d/crontest)

■rootユーザ以外に書き込み権限がある場合

# ls -la /etc/cron.d/crontest
-rw-rw-rw- 1 root root 117  2月 24 00:18 2015 /etc/cron.d/crontest

こちらの場合も、ログに「BAD FILE MODE」と表示されていました。

Feb 24 13:05:01 centos6 crond[7999]: (root) BAD FILE MODE (/etc/cron.d/crontest)
ファイルの所有者がroot以外の場合

ファイルの所有者がrootユーザ以外の場合もエラーとなります。

# ls -la crontest
-rw-r--r-- 1 tamohiko tamohiko 116  2月 24 13:22 2015 crontest

ファイルの所有者がroot以外ですので、「WRONG FILE OWNER」とエラーが表示されています。

Feb 24 13:26:01 centos6 crond[7999]: (root) WRONG FILE OWNER (/etc/cron.d/crontest)
スケジュール設定に間違いがある場合

スケジュールの時間設定に間違いがあった場合も、エラーログがでます。
下記のログから「分」の部分に設定の間違いがあることが分かります。

Feb 24 12:58:01 centos6 crond[7999]: (CRON) bad minute (/etc/crontab)

メールの確認

環境変数で設定してあるメールにcronの結果が飛ぶのでその中身に、エラーの原因が記載されていることがあります。

エラーメール内容
Subject: Cron  /root/cron-test.sh
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
Date: Tue, 24 Feb 2015 05:00:01 +0900 (JST)
Status: R

/bin/bash: /root/cron-test.sh: No such file or directory

今回はファイルが無いといっているので、シェルスクリプトのファイル名違うということが分かります。

パーミッション・所有者の確認

/etc/crontabや/etc/cron.d/内の設定ファイルを確認してみてください。

  • パーミッションは644
  • 所有者はrootで!

パスの確認

cronに設定してるスクリプトなどのパスが通っているか確認してください。環境設定部分のPATH部分で設定していない場合は、フルパスで記述する必要があります。

改行コードの確認

Windows環境で作ったファイルをlinux環境に持ってくると、改行コードの違いから動作しないことがあります。改行コードがWindows標準の「CR+LF」だと動作しないので、「LF」に変更してください。

windowsでファイルを作成する場合は、サクラエディタとかなら改行コードの指定ができるはずです。他のエディタでも改行コードが指定できればそれでも良いです。

crondが実行されているか確認

設定ファイルを確認したけど問題ないよ・・・
という場合は「cron」自体が動作しているか確認してみてください。

CentOS6までは「service」コマンドを使用することで、動作しているか確認できます。

crondが動作している場合

実行中と表示されて、動作していることが分かります。

# service crond status
crond (pid 1746) を実行中...

crondが動作していない場合

停止していますと表示され、停止していることが分かります。

# service crond status
crond は停止しています

停止している場合はサービスを起動してください。

crondの起動
# service crond start

自動起動設定の確認

crondが自動起動されているかも念のために確認しておきましょう。

# chkconfig --list crond
crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off

自動起動設定がされていない場合は、自動起動設定を行いましょう。

# chkconfig crond on

CentOS7からは・・・

CentOS7からはsystemctlを使用します。
(serviceコマンドでも確認できますが、CentOS7からはサービスの管理は「systemd」に変更されています。「systemd」について詳しくはこちらにまとめてあります。)

「crond」が動作している場合

「Active: active (running)」と表示されて「crond」が動作していることが分かります。

# systemctl status crond
crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
Active: active (running) since 木 2015-02-26 16:52:13 JST; 2min 34s ago
Main PID: 822 (crond)
CGroup: /system.slice/crond.service
mq822 /usr/sbin/crond -n

2月 26 16:52:13 localhost.localdomain systemd[1]: Started Command Scheduler.
2月 26 16:52:13 localhost.localdomain crond[822]: (CRON) INFO (RANDOM_DELAY...
2月 26 16:52:13 localhost.localdomain crond[822]: (CRON) INFO (running with...
Hint: Some lines were ellipsized, use -l to show in full.

「crond」が動作していない場合

起動していない場合はActive: inactive (dead)と表示されます。

# systemctl status crond
crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
Active: inactive (dead) since 木 2015-02-26 17:00:00 JST; 2s ago
Process: 822 ExecStart=/usr/sbin/crond -n $CRONDARGS (code=exited, status=0/SUCCESS)
Main PID: 822 (code=exited, status=0/SUCCESS)

2月 26 16:52:13 localhost.localdomain systemd[1]: Started Command Scheduler.
2月 26 16:52:13 localhost.localdomain crond[822]: (CRON) INFO (RANDOM_DELAY...
2月 26 16:52:13 localhost.localdomain crond[822]: (CRON) INFO (running with...
2月 26 17:00:00 localhost.localdomain systemd[1]: Stopping Command Schedule...
2月 26 17:00:00 localhost.localdomain systemd[1]: Stopped Command Scheduler.
Hint: Some lines were ellipsized, use -l to show in full.

起動していない場合は「crond」を起動させてください。

# systemctl start crond

自動起動設定の確認

自動起動設定の確認は下記のとおりです。

自動起動設定がされている場合は「enabled」と表示されます。

# systemctl is-enabled crond
enabled

自動起動設定がされていない場合は「disabled」と表示されます。

# systemctl is-enabled crond
disabled

自動起動設定

自動起動設定がされていない場合は、下記のコマンドで自動起動設定が出来ます。

# systemctl enable crond

 - Tips