UNIXの部屋 コマンド検索: crontab


※空白区切りで AND 検索 (例:「ファイル 削除」)

crontab スケジュールを登録。決められた時刻にプログラムを実行する。クーロン。

定期的に実行するコマンドを管理する。

日時を指定して、自動的にコマンドを実行することができる。設定方法は FreeBSD なら
% crontab 設定ファイル名
とし、Solaris なら
% echo '分 時間 日 月 曜日 コマンド名' | crontab
% crontab < 設定ファイル名
のどちらでもいい。当ページ管理人は、~/.crontab というファイルを作り、このファイルをエディタで編集してから、
% crontab ~/.crontab
として cron に反映する方法を好む。ただし、この方法だと cron に登録されているデータと ~/.crontab の内容が一致している保証はない、という欠点がある (crontab -e で直接編集しないように気をつける必要がある)。

オプション
  • -l 現在設定されている crontab データを表示する
  • -r 現在設定されている crontab データを解除する。

cron を設定した後は、必ず crontab -l で確認すること。もし動作がおかしいなら crontab -r で設定をクリアできるが、その後も必ず crontab -l で確認しよう。

設定ファイル書式
設定ファイルの書式は
分 時 日 月 曜日 コマンド
である。それぞれの書式は下記のとおり。
分 0-59
時 0-23
日 1-31
月 1-12
曜日 0-7 (0:日曜、1:月曜、2:火曜、3:水曜、4:木曜、5:金曜、6:土曜。7 は 0 と同じ日曜)
いくつかの例を下記に示す。
* * * * * command
⇒ 1分おきに command を実行する。
10 3 1 * * command
⇒ 毎月1日の3時10分に command を実行する。
0 12 * * 0 command
⇒ 毎週日曜日の12時に command を実行する。

実行結果はメールで自分自身に知らされる。メールを送ってほしくない場合は、
* * * * * command 1> /dev/null
と標準出力を捨てればよい。この場合はエラーが起こった時だけ (標準エラー出力に出力があった時だけ)メールが送られてくるので便利である。エラーが起ころうと絶対にメールを送ってほしくない場合は
* * * * * command >/dev/null 2>&1
とすればよい。
>> 用語集 リダイレクト *

なお、crontab で実行されるときには、ほとんどの環境変数が設定されていないので注意が必要。~/.cshrc・~/.login で設定している環境変数は設定されていないし、PATH も /bin:/usr/bin くらいにしか通っていない。そのため、command の部分に指定するのはシェルスクリプトにしておいて、シェルスクリプトの先頭で環境変数の設定を行い、その後いろいろなコマンドを実行するようにしておくのがよいだろう。

Tips.1
メールは ISO-2022-JP (いわゆる JIS コード) で送るというきまりがあるので、出力が EUC-JP や Shift_JIS などの日本語を含む場合は、
* * * * * command | nkf -j
と、nkf などで ISO-2022-JP に変換すればよい。
>> コマンド nkf *   qkc *   euctosj *   iconv *

Tips.2
cron の設定ファイルでは、
* * * * * cd foo/bar; command
というふうに、セミコロンで区切ることで複数のコマンドを記述することができる。その他にもシェルが解釈できる構文や * ? などのメタキャラクタも使用可能である。これは cron は書かれた行をそのままシェルに渡すからである。標準のシェルは sh なので、sh が解釈できるものは何でも書けるというわけだ。

ただし、設定ファイルの先頭で
SHELL=/bin/csh
などと書くと、sh でなく csh に渡されることになり、
* * * * * command >& /dev/null
といった csh 風の書き方ができるようになる (FOO=bar という変数の設定は、少なくとも FreeBSD では可能。他の OS ではダメかもしれない)。

Tips.3
cron では、1分より細かい単位で実行することはできない。もし 30秒ごとにコマンドを実行したい場合は
* * * * * date & sleep 30 ; date
などと書けばよい。
Tips.4
前処理のプログラムが正常終了した場合のみ、次のプログラムを実行したい場合は、
* * * * * command1 && command2
とする。
前処理プログラム A と B を並列実行し、A・B 両方が終了したらプログラム C を実行するには
* * * * * (commandA & commandB & wait) && commandC
とする。

Tips.5
極めてわかりづらいのだが、日と曜日の組み合わせだけは「OR」である。
0 0 1 * 2 command1
は、毎月1日の 0時0分と、毎週火曜日の 0時0分に実行される。よって、crontab の通常書式だけでは「13日の金曜日」を表現することはできない。

Tips.6
一部 cron 実装 (vixie-cron の系統を採用している FreeBSD・Linux 等) では、@reboot という書き方によって、OS 起動時に任意の処理を行うことができる。
@reboot command1
ただし、OS 起動だけではなく crond (デーモン) が起動した際、例えば
# service crond restart
などとした際に @reboot が発動するかは実装によるので確認してほしい。

cron の欠点
cron の欠点は以下の通り。
  • 1分単位でしか起動できない。例えば n 秒おきに起動、ということができない (できなくはないが、Tips3 のように小細工が必要になる)。
  • 登録した時刻にマシンが起動していないと、永遠に起動されない。
  • 指定した日が祝日なら、次の営業日に実行、というちょっと凝った指定ができない。
  • 重複起動防止の機能はない。プログラムを毎分実行するように設定したとして、もしプログラムの実行に 1分以上かかってしまっても、新たにプロセスがどんどん生成される。重複起動を避けたい場合は、個々のプログラムで排他制御をする必要がある。
  • Tips.4 のように、cron にて前処理・後処理を行うことは可能だが、「前処理のプログラムが異常終了した場合に手動リカバリ後にその次のプログラムから再開」といった賢いリカバリ作業はできない。

商用システムでは
cron は中小規模のシステムでは全く問題ないものの、大規模な商用システムでは上記のような欠点があるために、JP1・Senju(千手)・Hinemos・Tivoli などのジョブ管ツールを使うことが多い。
>> コマンド at *   cron *
>> 設定ファイル /etc/crontab *
>> 読み方 cron *