バイオインフォをやっている大学院生です。プログラミングのことなどを書きます。

cronでプログラムを定期的に実行する

cronとは

Macでプログラムを定期的に実行する手法を紹介します。cronとは、UNIX系のOSに入っているプログラムで、時間を指定してプログラムを実行することができます。また、「毎週日曜日に」や「毎月1日に」などというように、繰り返し実行させることが可能です。

cronを動かしてみる

Macで試しました。実行した環境のOSはmacOS Big Sur、シェルはbashを使っています。 まず、実行したいスクリプトを用意します。今回は、わかりやすいようにターミナルに実行された時間を出力するプログラムにします。

シェルスクリプトの準備

print_date.sh というファイルを作成し、次のように変更します。

#!/usr/bin/env bash
term="/dev/ttys000" # ttyコマンドの結果を入力
date > $term

ttyコマンドは、そのターミナルの名前を得るコマンドです。ttyコマンドで得られた結果にリダイレクトすることで、ターミナルに実行された時間を出力させます。 次に、chmod 700 print_date.shとして、このシェルスクリプトに実行権限を与えます。 この作業を忘れると、この記事の通り作業しても、実行できなくなってしまうので、注意してください。

次に、このシェルスクリプトが定期的に実行されるように、設定をしていきます。

cronの設定

cronの設定にはcrontabというコマンドを使用します。 crontab -eと入力すると、cronの設定を編集することができます。 次の行を書き加えてください。編集ができたら、エディタを保存して閉じてください。cronのインストールの許可が求められた場合、許可をしてください。

* * * * * [print_date.shがあるフォルダのパス]/print_date.sh

ここでは最初に*を5つ並べて書いています。この部分が、実行する時間を示している部分です。

それぞれの*は、左から順に次の要素を表しています。

何番目 表しているもの 範囲
1 0-59
2 0-23
3 1-31
4 1-12
5 曜日 0-7(0, 7が日曜日)

先ほどのように* * * * *とすると、毎分実行されるように設定されます。 他にも次のような使用例があります。

* * * * 0   #毎週日曜日
* */1 * * *   # 1時間ごと
* 8-12 * * * #毎日8, 9, 10, 11, 12時に実行
* 0,6,12,18 * * *    #毎日0, 6,12,18時に実行
* * 13 * * 5 # 毎月13日と、毎週の金曜日

ちなみに、この5つのフィールドで指定する他にも、文字列で指定する方法もあるようです。

@reboot         Run once, at startup.
@yearly         Run once a year, "0 0 1 1 *".
@annually       (same as @yearly)
@monthly        Run once a month, "0 0 1 * *".
@weekly         Run once a week, "0 0 * * 0".
@daily          Run once a day, "0 0 * * *".
@midnight       (same as @daily)
@hourly  

実装によって指定方法や挙動の違いがある可能性がありますので、細かい使い方などはcrontabのマニュアルを参照してください。自分の環境ではman 5 crontabで書き方を参照することができました。

実行結果

cronを設定してしばらく経つと、次のように指定したコンソールに表示がされていきました。

Mon Jan 18 19:32:00 JST 2021
Mon Jan 18 19:33:00 JST 2021
Mon Jan 18 19:34:00 JST 2021
Mon Jan 18 19:35:00 JST 2021
Mon Jan 18 19:36:00 JST 2021
Mon Jan 18 19:37:00 JST 2021
Mon Jan 18 19:38:00 JST 2021
Mon Jan 18 19:39:00 JST 2021

一分ごとにきちんとコマンドが実行されていることがわかります。

設定したコマンドの消去

今設定したコマンドを消したい場合、設定した時と同様にcrontab -eとしてエディタを開きます。エディタで、先ほど追加した行を削除すれば大丈夫です。 また、削除方法として、crontab -rが紹介されていることもあります。このコマンドは、確かに設定したcrontabを消去します。しかし、crontabに複数のコマンドを指定した場合、全てのコマンドを消去してしまうので、注意が必要です。

cronが動かない

cronはコマンド実行の際に何かあるとメールを送信するようになっているようです。mailコマンドで確認すると、cronからエラーメッセージが届いている可能性があります。print_date.shが実行できるようにパーミッションを与えるのを忘れた場合、それを知らせるメッセージが届いていました。 また、/usr/lib/cron/cron.allow/usr/lib/cron/cron.denyというファイルによってcronを使用できるユーザーが制御されているため、これらのファイルを確認することが有用であるかもしれません。