cronの使い方

cronとは

cronとは、多くのUNIX系のシステムで採用されている「定期的になにかを実行する仕組み」である。crondと呼ばれるデーモンが常駐しており、毎分ごとに実行すべきタスクがないかチェックし、あればそれを実行する。以下では、研究室サーバでcronを使う方法について紹介する。

なお、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を実行してみよう。研究室サーバに接続し、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に日付が追加されたはずだ。

crontabによる実行

ではいよいよ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から実行される場合はカレントディレクトリが変わってしまうので、ディレクトリなどの指定をすべて絶対パスにするのを忘れてはならない。