cronの設定 - 時間を指定して定期的にプログラムを自動実行する
cronを使うとサーバー上にあるプログラムを指定した時間に定期的に自動的に実行できる。 Windowsで言うとタスクスケジューラのようなもの。 用途としては、ウェブサイトでの定期的なAPIの実行、集計処理、バックアップなどがある。 各社のレンタルサーバーでもたいていコントロールパネルにて簡単に設定できるようになっている。
基本コマンド
ターミナル等で操作する場合は、crontabコマンドを使用する。
登録済みのcronの一覧を表示する。
crontab -l
cronを編集する。編集方法はviと同じ。
crontab -e
cronをすべて削除する。
crontab -r
記述例
ターミナル等でコマンドを直接記述する場合の例。 cronの書式は以下のようになっている。
分(0-59) 時(1-24) 日(1-31) 月(1-12) 曜日(0-7,0=7=日曜日) コマンド
数字を書くとその数字のときに実行、* を書くと毎回、*/6 のように書くとその数値毎の実行になる。
9時30分に実行。
30 9 * * * cd /htdocs/example/test.pl
3分おきに実行。
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57, * * * * /htdocs/example/test.sh
数字を羅列しても良いが、/(スラッシュ)を使って以下のようにシンプルに書ける。
*/3 * * * * /htdocs/example/test.sh
1時間おきに実行。 「*/1」は「*」でも良い。
0 */1 * * * /htdocs/example/test.sh
3時間おき、0~30分の間の10分おきに実行
0-30/10 */3 * * * /htdocs/example/test.sh
毎分実行(1分おき)。
* * * * * /htdocs/example/test.sh
7時~8時に10分おきに実行。
*/10 7-8 * * * /htdocs/example/test.sh
テキストファイルに実行結果を出力。
* * * * * /htdocs/example/test.sh > /htdocs/example/test.txt
複数のプログラムを実行する例。
0 */1 * * * /usr/local/bin/php /home/test/example.php 0 3 * * * /usr/local/pgsql/bin/vacuumdb -d DB名 -U ユーザ名 30 9 * * * cd /htdocs/example/; ./test.pl
cronの末尾に書くコマンドは、単にプログラムの実行ファイルのパスを指定するだけでなく、通常のLinuxコマンドと同様に記述でき、PHPやPerlなどのパスを指定できる。
/usr/bin/php8.3 /home/username/example.com/public_html/test.php
エラーが出る場合
コマンドは単にPHPなどのプログラムを指定するだけでなく、;(セミコロン)で区切ってcdなどのコマンドも羅列して1行で記述できる。
以下のようなcronのコマンドを書いたとする。
/usr/bin/php /home/username/hoge/test.php
例えばPHPであれば、実行するプログラムから require() などで別のプログラムを読み込んでいる場合、require(): Failed opening required や No such file or directory などの警告が出る。 その場合、実行するプログラムがあるディレクトリへcdで移動した後、プログラムを実行すればエラーが発生しない。 例えば上記を以下のように書き直す。
cd /home/username/hoge/ ; /usr/bin/php ./test.php
cdで「/home/username/hoge/」へ移動した後、「/usr/bin/php」で「test.php」を実行する。 サーバーの設定によってはPHPのパスを書かなくても実行できるが、書いておいた方が無難。
メールで通知が届かないようにする
cronを実行すると、たいていデフォルトではpostmasterなどにメールが届くようになっている。 メールが届かないようにするにはコマンドの末尾に「>/dev/null」などを追加する。
cd /home/example/www/abc/ ; /usr/local/bin/php ./cron.php 1> /dev/null
- >/dev/null
- 標準出力を破棄する。1>/dev/null も同じ
- >/dev/null 2>&1
- 標準出力と標準エラー出力の両方を破棄する。&>/dev/null も同じ。
レンタルサーバー
たいていのレンタルサーバーではコントロールパネルからcronが設定できるようになっている。 基本的に各テキストボックスにコマンドおよび実行する時間を入力するようになっている。 毎時0分に実行する場合は、分に「0」、それ以外(時間、日、月、曜日)は「*」を入力する。
cd /home/example/www/abc/ ; /usr/local/bin/php ./cron.php 1> /dev/null
PHPのパスはレンタルサーバーによって異なる。
- さくらのレンタルサーバ
- /usr/local/bin/php
- エックスサーバー、シンレンタルサーバー
- /usr/bin/php8.3 など
- コアサーバー
- /usr/local/bin/php
- ConoHa WING
- /usr/bin/php
以下記述例。
エックスサーバーは以下のとおり。
cd /home/ユーザー名/ドメイン名/public_html/(中略)/cron.phpがあるディレクトリ名/ ; /usr/bin/php8.3 ./cron.php 1> /dev/null
さくらのレンタルサーバは以下のとおり。
cd /home/ユーザー名/www/(中略)/cron.phpがあるディレクトリ名/ ; /usr/local/bin/php ./cron.php 1> /dev/null
コアサーバーのV1プランは直接PHPを実行できず、cron.shなどシェルスクリプトを用意してそこから実行する必要がある。 具体的には cron.sh など適当なシェルを用意し、コントロールパネルにてシェルのパスを登録する。 具体的にシェルには以下のような PHP を実行するコマンドを書く。
#!/bin/sh /usr/local/bin/php /virtual/ユーザー名/public_html/ドメイン名/(中略)/ファイル名.php
このシェルを実行するように以下のようなcronを登録する。
/virtual/ユーザー名/public_html/ドメイン名/(中略)/cron.sh >/dev/null 2>&1
実行時間の調整
cronは多くの人が0分丁度に実行する。 そのためその瞬間サーバーの負荷が高くなる。 これは自サーバーだけではない。 cronで他のサーバーのAPIなどをたたく場合、相手側のサーバーも負荷が高くなる。 その際、正常にデータを取得できないこともある。 実際私はそういう経験がある。 もしcronでデータが取得できないことが多い場合は、実行する時間を変更してみると良いかもしれない。
また0分以外にも、18~24時頃はサイト自体が混在して重くなることがある。 海外サーバーの場合は、その国の18~24時頃。