cronとは、多くのUNIX系のシステムで採用されている「定期的になにかを実行する仕組み」である。crond
と呼ばれるデーモンが常駐しており、毎分ごとに実行すべきタスクがないかチェックし、あればそれを実行する。以下では、研究室サーバでcronを使う方法について紹介する。
なお、cronは英語的には「クロン」もしくは「クローン」と発音するのだが、日本では慣習的に「クーロン」と発音されることが多い。
cronは、crontabファイルと呼ばれるファイルに書かれたスケジュールに従ってタスクを実行する。crontabファイルは以下のようなフォーマットになっている。
分 時 日 月 曜日 コマンド
例えば、毎時0分ちょうどにcommand
というコマンドを実行したければ、
0 * * * * * command
と書く。*
が書かれたところは、全ての状態がマッチする。スケジュールの書き方には様々な指定方法があるが、とりあえず「毎分」「毎時」「毎日」の三種類を知っておけば十分であろう。
# 毎分実行する
* * * * * * command
# 毎時15分に実行する(一時間に一度実行)
15 * * * * * command
# 毎日 午前4時00分に実行する(一日に一度実行)
0 4 * * * * command
crontabファイルは、例えば/var/spool/cron
以下にあるが、直接編集するのではなく、crontab
というコマンドで編集する。crontab
を実行すると、エディタ(研究室サーバではVim)が立ち上がり、crontabファイルを開いてくれるので、適当に編集して保存すると、次からスケジュールに従って実行してくれる。
では実際にcronを実行してみよう。研究室サーバに接続し、cron
というディレクトリを作ろう。
mkdir cron
cd cron
ここで、実行すべきスクリプトを作る。例えばhello.sh
というシェルスクリプトを作ろう。
vim hello.sh
hello.sh
には、実行時の日付をdate.log
に保存する命令を書く。
date >> date.log
>>
は出力結果をファイルに追記せよ、という意味だ。スクリプトを実行してみよう。
source hello.sh
同じディレクトリにdate.log
が出力されたはずだ。中身を見てみよう。
$ cat date.log
2022年 5月 12日 木曜日 15:21:59 JST
確かにdate
コマンドの実行結果が保存されている。このように、cronで実行するスクリプトは、実行結果をどこかに保存するようにしておく。
次に、スクリプトを直接実行できるようにする。そのために、スクリプトに実行権限をつける。
chmod u+x hello.sh
このコマンドの意味は、ユーザ(u)に、実行権限(eXecutable)をつけろ、という意味だ。これによりhello.sh
を直接実行できるようになる。試してみよう。
./hello.sh
実行後、またdate.log
を見てみよう。
$ cat date.log
2022年 5月 12日 木曜日 15:21:59 JST
2022年 5月 12日 木曜日 15:24:52 JST
二行に増えたはずだ。
さて、cronを使うにあたり最も重要なのは、cronからスクリプトを実行された時のカレントディレクトリがホームディレクトリになる(cd
で戻る場所になる)ということだ。例えばホームディレクトリからhello.sh
を実行してみよう。
cd
./cron/hello.sh
すると、cron
以下ではなく、実行した場所の直下にdate.log
が作られる。それは困るので、スクリプト内のファイルはすべて絶対パスで書いておかなければならない。
先程のスクリプトは以下のような内容であった。
date >> date.log
これは、date
コマンドの実行結果を、「カレントディレクトリ」のdate.log
に保存せよ、という意味だ。今は~/cron
で実行しているので~/cron/date.log
に保存されるば、別の場所から実行されると、別の場所に保存されてしまう。それを防ぐために、date.log
の場所を絶対パスで書きなおす。
date >> ~/cron/date.log
~/
は、ユーザのホームディレクトリを意味する。これにより、どこから実行しても~/cron/date.log
に結果が保存される。一つ上のディレクトリから実行してみよう。
cd
./cron/hello.sh
~/cron/date.log
に日付が追加されたはずだ。
ではいよいよcronに登録しよう。そのためにはcrontab -e
という命令を実行する。これはcrontabファイルを修正するよ、という意味だ。
crontab -e
研究室サーバで実行すると以下のようなエラーがでるが、とりあえず無視してエンターキーを押してかまわない。
E79: Cannot expand wildcards
Press ENTER or type command to continue
Vimが立ち上がったら、以下を入力しよう。
* * * * * ~/cron/hello.sh
入力したらファイルを保存してVimを終了せよ(ESCを押してShiftを押しながらZを二回)。
crontab: installing new crontab
と表示されたら成功だ。登録されたか確認しよう。現在のcrontabファイルを表示するのはcrontab -l
だ。
$ crontab -l
* * * * * ~/cron/hello.sh
ここまで正しく設定されていれば、毎分date.log
が追加されていくはずだ。ファイルを監視しよう。
$ tail -f date.log
入力待ちになるのでしばらく待つ。1分まって行が勝手に追加されたら成功だ。
このままでは毎分ログが追加されてしまうので、スケジュールを消しておこう。またcrontab -e
を実行し、crontabファイルを編集する。
crontab -e
Vimが立ち上がったら、先程入力した行を(例えばdd
により)消去し、ファイルを保存せよ。
crontab -l
を実行し、何も表示されなければ正しく修正されている。
$ crontab -l
$
cronの使い方を紹介した。ウェブスクレイピング、ファイル容量の監視など、定期的になにかを実行したい時に便利なコマンドであるので覚えておきたい。ただし、実行する時にミスがあっても分かりづらいので、必ずcronを経由しない方法で動作確認をすること。また、cronから実行される場合はカレントディレクトリが変わってしまうので、ディレクトリなどの指定をすべて絶対パスにするのを忘れてはならない。