cron

Raspberry Pi (Linux)で定期的にコマンドを実行する方法であるcronについてまとめておきたいと思います。

 

Cronの設定

Cronの書き方

以下のコマンドを実行し、書式に従って設定を書いていきます。

1
$ crontab -e

crontabで設定するスケジュールの書式は下記のとおりとなっていて、空白またはタブで区切られた5つのフィールドで構成されています。フィールドは左から「分」「時」「日」「月」「曜日」を指定することができます。私には少しばかり馴染めない順番だと感じています。

* * * * * [実行コマンド]
1
分 時 日 月 曜日 '実行したいコマンドまたはスクリプト'

「分」「時」「日」「月」「曜日」のフィールドに指定できる数値は下記のとおりとなっていて、それを「リスト(list)」「範囲(range)」「間隔(step)」といった設定方法と組み合わせてスケジュールを設定します。

設定項目 数値
0-59
0-23
1-31
1-12
曜日 0-7 (0または7は日曜日)
0=日、1=月、2=火、3=水、4=木、5=金、6=土、7=日

スケジュールの設定は数値以外にも「*」(アスタリスク)が設定できます。「*」(アスタリスク)は各項目で設定できる全ての値を設定していることになります。例えば下記の設定では毎分コマンドが実行されます。

* * * * * [実行コマンド]

スケジュールの設定は、下記の指定方法を使用することでより柔軟に実行する時間を設定することが出来ます。

指定方法 設定例 説明
リスト指定(list) 0,10,20,30 「,」で区切ることで複数指定が可能
分フィールド指定した場合は0,10,20,30分に実行します。
範囲指定(range) 1-5 「-」で範囲指定が可能
月フィールドで指定した場合1,2,3,4,5月に処理を実行します。
間隔指定 */10 「*/数値」で間隔を設定することが可能
分フィールドで指定した場合、10分間隔で処理を実行します。「/」の後ろに指定した値の間隔で処理を実行します。

「リスト」や「範囲」をあわせて指定することも可能で時間フィールドで「1,6,9-12」と指定した場合、1時、6時、9時、10時、11時、12時に処理を実行します。


以下のコマンドでCronの設定内容を確認できます。

1
$ crontab -l

注:”crontab -r”としてしまうとCronの設定が全て削除されてしまいます

Cronの起動、再起動、停止、ステータス確認

Cronの起動

1
$ sudo /etc/init.d/cron start

Cronの再起動

1
$ sudo /etc/init.d/cron restart

Cronの停止

1
$ sudo /etc/init.d/cron stop

Cronのステータス確認

1
$ sudo /etc/init.d/cron status

Cronがうまく動かない場合の対処法

Cronがうまく動いてくれない場合があると思います。そんなときは以下の手順で確認してみると良いです。

Cronが動いているか確認する

上記のステータス確認のコマンドでCronが動いているか確認してみます。

1
$ sudo /etc/init.d/cron status

正常に動いていれば以下のように表示されます。”Active”のところが”active (running)”になっています。

1
2
3
4
5
6
7
8
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-08-29 11:30:22 JST; 3 days ago
Docs: man:cron(8)
Main PID: 305 (cron)
Tasks: 1 (limit: 877)
CGroup: /system.slice/cron.service
└─305 /usr/sbin/cron -f -L 15

動作が停止しているときは以下のように表示されます。”Active”のところが”inactive (dead)”になっています。

1
2
3
cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Sun 2021-08-29 11:30:22 JST; 3 days ago

ログを確認してみる

デフォルトではCronのログが出力されないようになっているため、rsyslogの設定ファイルを編集します。

1
$ sudo vi /etc/rsyslog.conf

以下の行のコメントアウトを解除(先頭の”#”記号を削除)します。

1
cron.*                          /var/log/cron.log

ファイルを閉じて、rsyslogを再起動します。

1
$ sudo /etc/init.d/rsyslog restart

次に出力するログのレベルを設定します。

1
$ sudo vi /etc/default/cron

出力したいログのレベルを”EXTRA_OPTS=””のところに書き込みます。レベルは数字の足し算で設定するようです。

1
2
3
4
5
6
7
8
# For quick reference, the currently available log levels are:
#   0   no logging (errors are logged regardless)
#   1   log start of jobs
#   2   log end of jobs
#   4   log jobs with exit status != 0
#   8   log the process identifier of child process (in all logs)
#
EXTRA_OPTS='-L 15'

ファイルを閉じて、Cronを再起動します。

1
$ sudo /etc/init.d/cron restart

ログファイルを確認します。

1
tail -f /var/log/cron.log

スクリプトの実行権限を確認する

以下のコマンドを実行し、対象のスクリプトファイルの権限を確認します。実行権限が無い場合はchmodコマンドで実行権限を付与してあげてください。

1
$ ls -l '対象のスクリプトファイル'

スクリプトの内容を確認する

スクリプトをCronで実行する場合、ホームフォルダが実行フォルダになります。スクリプト内でディレクトリの作成や削除、ディレクトリ移動を行う場合にスクリプトファイルを基準とした相対パスで記述しているとエラーになる場合が多いです(私もこれでハマりました)。

Cronで実行するスクリプトを作成する際は、パスは絶対パスで書くようにしておくと事故が少ないようです(それか上記の特性を頭に入れて書く)。