cronやcrontabという言葉を聞いたことがありますか?
cronやcrontabについて知っていることを聞いてみると、きっと以下のような答えが返ってくると思います。
・設定方法が難しい
・正しく設定できたかどうかを確認することが難しい
・設定を間違えたときの影響範囲が大きいので、設定を変更するのが怖い
そこで、この記事ではcron/crontabについてザックリ説明したあとで、設定を確認するためのPerlスクリプト(懐かしくないですか!?)を紹介します!
このPerlスクリプトを日本語で取り上げるのは、この記事が初めてだと思います。
#Googleで言語指定無しで検索しても、そもそも65件しかでてきませんでした。
cron/crontabを使うあなたに幸あらんことを!
cron/crontabとは
cronもcrontabも、Linuxで定期的にジョブを実行するために使用するソフトウェアです。
以下のような役割分担になっています。
ソフトウェア | 役割 |
---|---|
cron | 定期実行を担当するデーモン(ソフトウェア) |
crontab | cronのスケジュール設定を担当するソフトウェア |
cronが動作しているか確認しよう
何はともあれcronデーモンが動作していないと、定期実行はされません。
一般的にはLinuxディストリビューションをインストールすれば、cronデーモンが自動的に起動するはずですが、念の為確認しましょう。
service cron status
以下のように「Active: active (running) …」と表示されれば動作しています。
● cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled) Active: active (running) since 木 2018-06-14 07:10:48 JST; 1h 44min ago (省略)
Linuxディストリビューションによっては、以下のコマンドで動作を確認しましょう。
/etc/rc.d/init.d/crond status
こちらは動作していると以下のように表示されます。
crond (pid 1213) is running…
動作する日時を設定しよう
cronデーモンが動作していることが確認できたら、実際に設定を書いてみましょう。
設定方法は?
cronの設定方法には、(crontab -rの実行事故を防ぐために)様々な流派があるようです。
- (事故を気にせず)crontab -eコマンドで編集する派
- crontabコマンドを、crontab -iコマンドに置き換える派
- 好みのテキストエディタで設定ファイルを作成してから、crontab filenameコマンドで反映する派
私がおすすめするのは、3つ目の「crontab filenameコマンドで反映する派」です。
別途設定ファイルを作成しておくことで、以下のようなメリットがあります。
- gitを使ってバージョン管理できる(間違えても苦もなく戻せます)
- PerlのSchedule::Cron::Eventsモジュールで動作予定を予測できる(後で紹介します)
設定書式は?
確認方法を紹介する前に、まずは設定方法を簡単に説明しておきましょう。
ここでは、Linux Mint 18.3 Xfceエディションに初めからインストールされているテキストエディタ(xed)で設定ファイルを書いてみました。
1行目の前半の「0 15 * * *」部分の意味を説明しましょう。
これは、「0分 15時 (任意)日 (任意)月 (任意)曜日」と読み、つまり毎日15時0分になったら何かを実行するという意味です。
実行する内容は、後半の「echo `date` “固定指定の例” >> cronlog.txt」で、実行時刻と「固定指定の例」をcronlog.txtに出力するイメージです。
2行目の前半の「5,10 2 * * *」は、「5分または10分 2時 (任意)日 (任意)月 (任意)曜日」と読み、つまり毎日2時5分と2時10分になったら何かを実行します。
3行目の前半の「5 2-5 * * *」は、「5分 2時から5時 (任意)日 (任意)月 (任意)曜日」と読み、つまり毎日2時5分、3時5分、4時5分、5時5分になったら何かを実行します。
4行目の前半の「*/5 * * * *」は、「0分を基準として5分間隔 (任意)時 (任意)日 (任意)月 (任意)曜日」と読み、つまり5分間隔で何かを実行します。
ただし、最後の間隔指定は、他の記事とは少し違うことが書いてありますので、注意してください。
下の黒枠内をゆっくり丁寧に読んでください。
0時0分、7分、14分、…、49分、0時56分、1時3分(0時56分の7分後)、…
ですが、実際は次のように動作します。
0時0分、7分、14分、…、49分、0時56分、1時0分(0分に戻る。ここだけ4分間隔)、…
ちょっと、直感的ではありませんね。
7分間隔だけでなく、11分間隔とか、25分間隔とか、60を割り切れない時間間隔を設定するときにハマりがちですので、気をつけましょう。
PerlのSchedule::Cron::Eventsモジュールを使って確認しよう
複雑な例だと以下のような書き方も許容されます。
*/25 9-10 1-7 1,12 0 echo `date` “複雑な例” >> cronlog.txt
さてみなさん、これがいつ実行されるか、正しくわかりますか?
私はまったく自信がありません!(断言)
実は、こういった複雑な例も動作予定を推測してくれるSchedule::Cron::EventsモジュールというPerlモジュールが用意されています。
そして、これを利用しているPerlスクリプトがGitHubで公開されています。
参考:https://github.com/kohts/Schedule–Cron–Events/blob/master/cron_event_predict.plx
このスクリプトには少し問題がありますので、問題を修正して、上記の複雑な例がいつ実行されるか確認してみましょう!
この記事では、Linux Mint 18.3 Xfceエディションで動作を確認していますが、他のLinuxディストリビューションでも概ね同じだと思います。
(1)以下のコマンドを入力して、必要なパッケージをインストールします。
sudo apt install libschedule-cron-events-perl
(2)以下のコマンドを1行ずつ順番に入力して、cron_event_predict.plxをダウンロードし、実行権限を付与します。
wget https://raw.githubusercontent.com/kohts/Schedule--Cron--Events/master/cron_event_predict.plx chmod +x cron_event_predict.plx
(3)Linux Mintでも動作するように修正し、バグを修正して(笑)、ついでに日本人が読みやすいように出力を変更します。
変更前(1):
#!/usr/local/bin/perl -w
変更後(1):
#!/usr/bin/perl -w
変更前(2):
open (IN, '<$filename') || die "Unable to open '$filename' for read: $!";
変更後(2):
my @wd = qw(日 月 火 水 木 金 土); open (IN, "< $filename") || die "Unable to open '$filename' for read: $!";
「’」を「”」に変更するのが主な修正です。
※@wdは、変更後(3)で使っています。
変更前(3):
my $date = localtime( timelocal($obj->nextEvent) );
変更後(3):
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( timelocal($obj->nextEvent) ); my $date = sprintf("%4d/%02d/%02d(%s) %02d:%02d", $year+1900, $mon+1, $mday, $wd[$wday], $hour, $min);
(4)任意のテキストエディタで、test_complexファイルを作成し、以下の内容を入力します。
*/25 9-10 1-7 1,12 0 echo `date` “複雑な例” >> cronlog.txt
(5)以下のコマンドを入力し、実行予定を確認します。
./cron_event_predict.plx -f 30 test_complex
以下のように表示されたでしょうか。
# Original line: */25 9-10 1-7 1,12 0 echo `date` “複雑な例” >> cronlog.txt 2018/12/01(土) 09:00 - predicted future event 2018/12/01(土) 09:25 - predicted future event 2018/12/01(土) 09:50 - predicted future event 2018/12/01(土) 10:00 - predicted future event 2018/12/01(土) 10:25 - predicted future event 2018/12/01(土) 10:50 - predicted future event 2018/12/02(日) 09:00 - predicted future event 2018/12/02(日) 09:25 - predicted future event 2018/12/02(日) 09:50 - predicted future event 2018/12/02(日) 10:00 - predicted future event 2018/12/02(日) 10:25 - predicted future event 2018/12/02(日) 10:50 - predicted future event 2018/12/03(月) 09:00 - predicted future event 2018/12/03(月) 09:25 - predicted future event 2018/12/03(月) 09:50 - predicted future event 2018/12/03(月) 10:00 - predicted future event 2018/12/03(月) 10:25 - predicted future event 2018/12/03(月) 10:50 - predicted future event 2018/12/04(火) 09:00 - predicted future event 2018/12/04(火) 09:25 - predicted future event 2018/12/04(火) 09:50 - predicted future event 2018/12/04(火) 10:00 - predicted future event 2018/12/04(火) 10:25 - predicted future event 2018/12/04(火) 10:50 - predicted future event 2018/12/05(水) 09:00 - predicted future event 2018/12/05(水) 09:25 - predicted future event 2018/12/05(水) 09:50 - predicted future event 2018/12/05(水) 10:00 - predicted future event 2018/12/05(水) 10:25 - predicted future event 2018/12/05(水) 10:50 - predicted future event
あれ、曜日のところに「0」を指定したので、第1日曜日だけ実行されるかと思ったらだいぶ違いますね。
このように、cron_event_predict.plxを使用すると、ミスも発見できるので超おすすめです(汗)
コマンド部分の入力内容を確認する
設定ファイルの各行の前半部分(日時指定のところ)は、確認する方法がわかりました。
今度は、後半部分(コマンド指定のところ)をどのように確認すればよいでしょうか。
残念ながら入力したコマンドをcronが正しく認識できるか確認する方法はなさそうです。
実際にcronが実行するのを待つしかないんですね…。
ただ、気をつけたいのは1点だけです。
%(パーセント記号)は、\(円マーク)でエスケープする必要があります。
以下のようにコマンドで%(パーセント記号)を使いたい場合は…
echo `date` "パーセント記号の例" >> cronlog_`date +%Y%m%d`.txt
crontabの設定ファイルに書き込むときに、%(パーセント記号)の直前に\(円マーク)を挿入します。
* * * * * echo `date` "パーセント記号の例" >> cronlog_`date +\%Y\%m\%d`.txt
これで問題なく動作するでしょう。
設定ファイルをcrontabに反映する
任意のテキストエディタで作成した設定ファイル(test1ファイルとします)を、cronに反映するには、以下のコマンドを入力します。
crontab test1
安全に運用するなら、test1をgitで管理するといいでしょう。
gitについては、以下の記事で説明されていますので、ぜひご覧ください!
まとめ
今回は、任意のコマンドを定期的に実行できるcron/crontabを紹介しました。
特に実行タイミングの設定内容を確認することが難しいので、そのためにGitHubで公開されているcron_event_predict.plxを少し変更して使用する方法を紹介しました。
cron/crontabの設定を確認することは、非常に厄介ですが、日付部分(実行タイミング)だけでも確認できると安心感が違うのではないでしょうか?
cron_event_predict.plxは、日本語のサイトでは紹介されていないようですので、本邦初公開ですね!(言い方が古い)
ぜひお試しください。