cronで定期実行する基本|crontabの5つの欄の読み方、動かないときの原因と確かめ方
よく使う指定の例
実際によく使う指定を、目的別に並べます。左の5つの欄だけを見れば、何をしたいかが読み取れるようになることを目指します。
| やりたいこと | 時刻の指定 |
|---|---|
| 5分ごとに実行 | */5 * * * * |
| 毎時0分に実行 | 0 * * * * |
| 毎日3時30分に実行 | 30 3 * * * |
| 平日の朝9時に実行 | 0 9 * * 1-5 |
| 毎週日曜の23時に実行 | 0 23 * * 0 |
| 毎月1日の0時に実行 | 0 0 1 * * |
| 8時から18時まで、2時間ごとに実行 | 0 8-18/2 * * * |
「毎分」になってしまう書き間違い
* 3 * * * と書くと、「3時台の毎分」、つまり3時0分から3時59分まで60回実行されます。「毎日3時に1回」のつもりなら、分の欄に 0 を入れて 0 3 * * * と書きます。時刻を指定するときは、分の欄から決めるのが失敗しないコツです。
日と曜日を両方指定するときの注意
日の欄と曜日の欄の両方に * 以外を書くと、多くの cron の実装では「どちらかに当てはまれば実行」という扱いになります。たとえば 0 9 13 * 5 は「13日の金曜日」ではなく、「毎月13日」と「毎週金曜日」の両方で実行されます。「第一月曜日だけ」のような条件は、時刻の指定だけでは書けないので、次のように実行するコマンドの側で日付を判定します。
0 9 1-7 * * [ "$(date +\%u)" = 1 ] && /home/user/bin/report.sh
日が1〜7日の朝9時に起動し、その日が月曜日(date +%u が1)のときだけ report.sh を実行する、という書き方です。% の前の \ については、次の章で説明します。
特別な指定
多くの実装では、5つの欄の代わりに次のような短い指定も使えます。
@reboot:マシンの起動時に一度実行する。@hourly、@daily、@weekly、@monthly、@yearly:毎時・毎日・毎週・毎月・毎年に一度実行する。
@daily は 0 0 * * * と同じ意味です。分かりやすい反面、実行時刻が0時0分に固定されるので、時刻を選びたいときは5つの欄で書きます。
手で動くのに cron では動かない原因
cron でいちばん多いつまずきが、「ターミナルで実行すると動くのに、cron に登録すると動かない」というものです。原因の多くは、cron がコマンドを実行するときの環境が、ふだんのターミナルとは違うことにあります。

1. PATH が最小限になっている
ターミナルでは、シェルの設定ファイルによって PATH(コマンドを探す場所の一覧)が広く設定されています。cron から実行されるときは、PATH が /usr/bin:/bin のような最小限の内容になっていることが多く、自分でインストールしたコマンドが見つからずに失敗します。
対策は、コマンドを絶対パスで書くことです。コマンドの場所は which コマンド名 や command -v コマンド名 で調べられます。crontab の先頭に PATH=/usr/local/bin:/usr/bin:/bin のような行を書いて、PATH をまとめて指定する方法もあります。
2. カレントディレクトリが違う
ターミナルでは、今いるディレクトリを基準に相対パスでファイルを指定できます。cron から実行されるときの基準は、多くの場合その利用者のホームディレクトリです。スクリプトの中で ./data.csv のような相対パスを使っていると、ファイルが見つからなくなります。
スクリプトの中ではファイルを絶対パスで書くか、スクリプトの最初で cd /home/user/project || exit 1 のように作業ディレクトリへ移動しておきます。
3. % 記号が改行として扱われる
crontab のコマンド欄では、% が改行の意味を持つ特別な記号として扱われます。日付をファイル名に入れようとして date +%Y%m%d と書くと、そこでコマンドが途切れて意図どおりに動きません。crontab に直接書くときは、date +\%Y\%m\%d のように % の前に \ を付けます。スクリプトファイルの中に書く場合は、この扱いは関係ありません。
4. シェルの違い
cron は、特に指定しなければ /bin/sh でコマンドを実行します。ふだん使っているシェルが bash や zsh で、それにしかない書き方を crontab に直接書いていると、エラーになることがあります。複雑な処理はスクリプトファイルにまとめ、先頭行で使うシェルを指定しておくと確実です。










