今号では、cron でタスクを追加する際の tips、スクリプト形式のタスクの内容を、もう少し深堀りして説明します!
crontab 設定の tips
時間指定方法
- 範囲指定する
– (ハイフン) を指定すると、「7時から 9時まで」のように、指定された範囲内のすべての値でジョブを実行することができます。- 【例1】毎日 7時から 9時までの毎分実行:* 7-9 * * *
- 【例2】毎月 1日から 5日までの毎日 10時に実行:0 10 1-5 * *
- 【例3】毎週月曜日から金曜日までの毎日 9時に実行:* 9 * * 1-5
- 複数の値を指定する
, (カンマ) を指定すると、「10時と 12時」のように、複数の値を同時に指定することができます。- 【例1】毎日 10時と 12時に実行:* 10,12 * * *
- 【例2】毎月 10日、20日、30日のみ 10時に実行:0 10 10,20,30 * *
- 【例3】毎週月、水、金曜日の 9時30分に実行:30 9 * * 1,3,5
- 間隔値を指定する
/ (スラッシュ) を指定すると、「毎時 15分ごと」のように、ジョブを実行する間隔を指定することができます。- 【例1】15分ごとに実行:*\15 * * * *
- 【例2】毎日 9時から 17時までの間、30分ごとに実行:*/30 9-17 * * *
- 【例3】3日ごとに、0時0分に実行:0 0 */3 * *
特殊な文字列オプション
最初にご説明した 分、時、日、月、曜日の 5つのフィールドで実行タイミングを指定する方法以外にも、特定の頻度を文字列で指定できるオプションがあります。
- @reboot:システム起動時に 1度だけ実行
- @yearly もしくは @annually:年に 1度だけ実行 (1月1日 00:00、年が変わった瞬間)
- @monthly:月に 1度だけ実行 (各月の 1日 00:00、月が変わった瞬間)
- @weekly:週に 1度だけ実行 (毎週日曜日 00:00、週が変わった瞬間)
- @daily もしくは @midnight:毎日 1度だけ実行 (毎日 00:00、日が変わった瞬間)
- @hourly:毎時 1度だけ実行 (毎時 00 分、時間が変わった瞬間)
例えば、システム起動時にのみ setup.sh というスクリプトを実行したい場合、下記のように設定します。
@reboot /path/to/startup.sh
/etc/crontab と crontab -e の違い
システム全体の crontab ファイル (/etc/crontab や /etc/cron.d 以下のファイル) を編集する場合、どのユーザが実行するかを明示する必要があります。
例えば、毎日 0時に daily.sh というスクリプトを実行するタスクを追加する場合、/etc/crontab と crontab -e では下記のように記載内容を変えます。
/etc/crontab の場合
0 0 * * * ykaino /path/to/daily.sh
crontab -e の場合
0 0 * * * /path/to/daily.sh
※ ykaino ユーザによる crontab -e 実行を想定しています。
スクリプト形式の tips
スクリプト形式のタスクは、基本的にはシェルスクリプトと同じ書き方で登録することができます。
基本的な構文、コマンド、if、for、while などの制御文、変数、関数なども使用できます。
シェルスクリプトについての具体的な説明はここではしませんが、スクリプト形式のタスクを登録する際の注意点を記載します。
コマンドは絶対パスで
crontab と同様、スクリプト内で実行するコマンドは絶対パスで記載することを推奨します。
カレントディレクトリに注意
cron がスクリプトを実行する際のカレントディレクトリは、通常はスクリプトを実行しているユーザのホームディレクトリになります。
そのため、スクリプト内でファイルを操作する際などは注意が必要で、コマンドと同様にファイルも絶対パスで記載しておきましょう。
必要であれば実行結果をログに出力
cron のタスク内で呼び出されたスクリプトやコマンドで何らかの問題が発生した場合、cron の実行結果として成功・失敗は確認できるものの、具体的にどの処理で失敗したのかが分からない場合があります。
この対策として、下記のように実行結果を明示的にログ出力させるようにしておくと安心です。
#!/bin/bash LOGFILE="/var/log/my_app/daily_job.log" # 成功メッセージをログ result() { echo "$(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOGFILE" }