Cron
このガイドでは、Gentoo Linux における cron デーモンのセットアップと利用方法を説明します。
cronの基礎
cronとは何か
cronはcrontabコマンドからの入力に基づいてスケジュールされたタスクを起動するためのデーモンです。cronは1分毎に起床し、ユーザのcrontabに実行すべきcronジョブがあるかどうかチェックします。
crontab は cron ジョブリストの名前であると同時に、このリストを編集するためのコマンド名でもあることに注意してください。
デファクトのcron
Portageにはいくつかのcron実装があります。これらはすべてよく似たインタフェースを持っていて、crontabもしくはそれに類似したコマンドを使用します。また、連続稼働しないシステムのcronと協調して動作するanacronと呼ばれる関連ユーティリティもあります。
現在利用可能な全てのcronパッケージはsys-process/cronbaseに依存しています。技術的には、どのcronパッケージもこのパッケージに依存していません。しかし、このパッケージは大部分のユーザに有益でcronに似た機能を提供します。
cronを動作させる前に、適切なcron実装が選択されていなければなりません。
どのcronが適しているか?
cronie
cronie (sys-process/cronie) は、由緒正しい vixie-cron のフォークで、[1] でホストされています。フォークであることから、cronie はオリジナルの vixie-cron と同じ機能を持っています。さらに、cronie は anacron の機能も実装していて、これは anacron USE フラグを通じて、デフォルトで有効化されています。他の cron システムから移行するときは、bug #551352 に記載されている通り、設定の差分に注意してください。さもないと期待されているジョブがまったく実行されないかもしれません。
dcron (Dillonのcron)
sys-process/dcron はシンプル、エレガント、かつセキュアな実装を目指しています。crontab での環境変数の設定はできません。すべての cron ジョブを /bin/sh から実行します。vixie-cron と同じように、それぞれのユーザがそれぞれの crontab を持つことができます。バージョン 4 以降は anacron のような機能を含んでいます。
- 高速、単純、不要な仕様がない。
- crontab へのアクセスを、例えばcronグループに所属するユーザだけに制限することができる。つまり、外部機能に依存しない。
fcron
sys-process/fcron は vixie-cron と anacron の置き換えを意図しています。連続稼働しないシステムで動作できるよう設計されていて、いくつかの拡張機能を持っています。それは「ジョブがスタートするための条件設定」、「ジョブの直列化制御」、「ジョブに nice 値を付与する機能」、「システム起動時に動作するジョブのスケジュール」です。
- 連続稼働しないシステムで動作するように設計されています。つまり、システム停止中のため動作できなかったジョブを再起動後に実行できます。
- 環境変数やその他多くのオプションをcrontabで設定できます。
- 多くの新機能と共に、拡張されたcrontab記述をサポートします。
- 各ユーザーはcron.allowとcron.denyでアクセス制御可能なcrontabを持つことができます。
bcron
sys-process/bcron はセキュアなオペレーションを念頭に置いて設計された cron システムです。これを実現するため、cron システムはいくつかのプログラムに分割され、それぞれが別のタスクに対して責任を持つことになりました。また、それらタスク間のコミュニケーションは厳格に制御されました。ユーザインターフェースは、よく似たシステム (例: vixie-cron) の単純な置き換えですが、内部の実装は大きく異なっています。
- vixie-cronの単純置き換え
- マルチプロセス設計
- 地域毎の夏時間サポート
anacron
anacronはcronデーモンそのものではなく、cronデーモンと組み合わせて動作します。anacronは指定された間隔でコマンドを実行し、システムが連続的に稼働することを前提とせず、シャットダウンのために実行されなかったジョブをリブート後に改めて実行します。通常、anacronは毎日動作するcronデーモンに依存しています。
cronを使う
インストール
目的にあった適切なcronを選択し、emergeしてください。
root #emerge --ask dcron選択されたcronデーモンがシステムのinitプロセスに追加されたことを確認してください。追加されていない場合、cronデーモンはジョブを開始しません。
root #/etc/init.d/dcron start
root #rc-update add dcron defaultオプションとして、cronデーモンのヘルパーとしてanacronをインストールすることは良い選択です。ただしfcronやdcronがインストールされていないことが条件です。
root #emerge --ask anacronanacronをインストールした場合は、anacronをシステムのinitプロセスに確実に加えてください。
root #/etc/init.d/anacron start
root #rc-update add anacron defaultanacronに関しては、通常initプロセスはありません。その代わり、anacronは別のcron実装を通して実行される必要があります。
cron の定義を通じて anacron を起動するのが1つの方法です。デフォルトでは、ほとんどの cron 実装が使用する、1時間毎に起動するスクリプトがインストールされます。これが当てはまらない場合でも、手動定義を通じて起動することはできます:
/etc/crontabcron 定義から anacron を実行する# anacron を 10 分毎に開始する
*/10 * * * * root /usr/sbin/anacron
# 代わりに、anacron によって提供されている 0anacron スクリプトを 1 時間毎に実行する
# 59 * * * * root /etc/cron.hourly/0anacron
システムcrontab
cronパッケージのインストール時のメッセージでcrontab /etc/crontabを実行するよう促されるでしょう。 この/etc/crontabファイルはシステムcrontabと呼ばれています。cronは/etc/cron.{daily,hourly,weekly,monthly}に記載されたスクリプトを実行するために、システムcrontabとsys-process/cronbaseを使用します。ここで、cronieだけが/etc/crontabに記述するだけで自動的にジョブを実行することに留意してください。一方、dcronは/etc/crontabを変更するたびにcrontab /etc/crontabを実行する必要があります。fcronユーザは、システムcrontabを設定するためにemerge --config sys-process/fcronを実行する必要があります。
さらに、システムcrontabで予約されたジョブは、crontab -lで示されるcronジョブのリストにおそらく現れないことを注記しておきます。
もちろんシステムcrontabをまったく使用しない選択をすることも可能です。dcronもしくはfcronを使用する場合、crontab /etc/crontabを実行してはいけません。cronie または bcronの場合は/etc/crontabの全ての行をコメントアウトして下さい。
sedコマンドでファイルの全ての行をすばやく簡単にコメントアウトできます。etc/crontabに対して次のコマンドを実行してください。
root #sed -i -e "s/^/#/" /etc/crontab信頼できるユーザーにcronへのアクセス権を与える
root 以外で cron デーモンにアクセスする場合は、このセクションが参考になるでしょう。そうでない場合は次のセクションに進んで下さい。
別のユーザーにcrontabへのアクセスを許可しても、そのユーザのcronジョブをroot権限で実行することはできません。root crontabの編集権限をユーザに与えるために、sudo (app-admin/sudo)を一読ください。詳細については Gentoo Sudo(ers) Guide を参照してください
選択した cron パッケージに関わらず、あるユーザーに crontab へのアクセスを許可する場合、そのユーザは cron グループに所属しなければなりません。例として、次のコマンドはユーザ larry を cron グループに追加します。
root #gpasswd -a larry cronユーザーをcronグループに追加した際は、そのユーザは一旦ログアウト後、再度ログインする必要があります。
dcron
dcronの場合、上記の手順だけでユーザーはcrontabにアクセスできるようになります。よってdcronユーザは次のセクションに進んでください。その他のユーザーはこのまま本セクションを読み進めてください。
fcron
fcronの場合は/etc/fcron/fcron.denyと/etc/fcron/fcron.allowを編集します。最もシステムを安全に保つ方法は、最初に/etc/fcron/fcron.denyで全てのユーザーを拒否して、次に明らかに許可したいユーザーのみ/etc/fcron/fcron.allowで許可することです。
もし、/etc/fcron/fcron.allowも/etc/fcron/fcron.denyも存在しない場合、cronグループに所属する全てのユーザーがcrontabの使用を許可されます。fcronのデフォルトはfcron.allowにallows all usersを記述した状態であり、cronグループに所属しているユーザーはfcrontabにアクセスできます。
all
もし、あるユーザー(ここで再度 larry を例にとります)が独自の cron ジョブをスケジュールしたい場合、次を /etc/fcron/fcron.allow に追加してください。
larry
cronie
cronie の場合は、単に /etc/cron.allow を編集します。
もし/etc/cron.allowしか存在しない場合、同ファイルに記載されているcronグループのユーザーのみがアクセス可能です。逆にもし空の/etc/cron.denyのみが存在する場合、すべてのcronグループユーザがアクセス可能になります。そのため、/etc/cron.allowが存在しない場合は、絶対に/etc/cron.denyを空にしてはいけません。
例として、ユーザー larry にアクセス権を与える場合、/etc/cron.allow に larry を追加します。
larry
cronジョブのスケジューリング
crontabを編集する手順はcronパッケージ毎に異なります。しかしそれらすべては同じ基本コマンド群をサポートしています。例えばcrontabの作成、置き換え、編集、消去、crontab中のジョブのリストアップといったことを実行します。次のリストは、それぞれのパッケージ毎にどのようにコマンドを実行するかを示しています。
| cronパッケージ | crontab編集 | crontab消去 | crontab新規作成 | cronジョブの表示 |
|---|---|---|---|---|
| dcron | crontab -e | crontab -d [user] | crontab file | crontab -l |
| fcron | fcrontab -e | fcrontab -r [user] | fcrontab file | fcrontab -l |
| cronie と bcron | crontab -e | crontab -r -u [user] | crontab file | crontab -l |
引数無しで消去コマンドを使用すると、現在のユーザのcrontabを削除します。
fcronの場合、fcrontabはcrontabのシンボリックリンクです。
これらのコマンドを実施する前に、crontabそのものを理解することがまず必要です。crontab中のそれぞれの行は、5つのフィードを次の順序で持ちます。分(0~59)、時間(0~23)、日(1~31)、月(1~12)、曜日(0~7、月曜日が1で日曜日が0もしくは7)。曜日と月は3文字の略称で表すこともできます。例えばmon、tue、jan、feb等です。それぞれのフィールドは範囲で表すこともできます。例えば1-5やmon-friといった記述です。カンマで分離された記述(例:1,2,3やmon,tue,wed)や刻み幅を使った範囲指定(例:1-6/2は1と3と5を示します)も可能です。
少し混乱するかもしれませんが、いくつかの記述例を見ればそれほど複雑でないことがわかるでしょう。
# /bin/falseを年中にわたり毎分に実行
* * * * * /bin/false
# /bin/falseを月・火・水曜日と毎月4日それぞれの1時35分に実行
35 1 4 * mon-wed /bin/false
# /bin/true を3月2日の22:25に実行
25 22 2 3 * /bin/true
# /bin/false を月・水・金曜の2時0分に実行
0 2 * * 1-5/2 /bin/false
日と曜日を組み合わせて記述する場合、もし日と曜日のどちらかを*にした場合、*でない方の記述が優先されます。逆に日と曜日の両方を*にした場合、それは毎日実行されることを意味します。
何がどう影響するのかをテストするために数個のcronジョブで確認しましょう。最初に次のファイルcrons.cronを作成します。
crons.croncrons.cronファイルを作成する#Mins Hours Days Months Day of the week
10 3 1 1 * /bin/echo "I don't really like cron"
30 16 * 1,2 * /bin/echo "I like cron a little"
* * * 1-12/2 * /bin/echo "I really like cron"
このcrontabファイルを上のコマンドリストの"crontab新規作成"コマンドを使って作成しましょう。
root #crontab crons.cronechoコマンドの出力はリダイレクトしない限り見ることができません。
スケジュールされたcronジョブを確認するため、コマンドリストの"cronジョブの表示 "に記載されているコマンドを使用します。
root #crontab -lcrons.cronとよく似たリストが得られるはずです。表示されない場合は、おそらく適切でないコマンドをcrontabに与えたのでしょう。
このcrontabは2ヶ月毎に、毎日、毎時間、毎分、"I really like cron"を出力するはずです。明らかにユーザはcronが気に入ったときにそれをするのでしょう。このcrontabは1月と2月の毎日16時30分に、"I like cron a little"を出力します。また1月1日の3時10分に"I don't really like cron"を出力します。
もしanacronを使っている場合は、このままこのセクションを読み続けてください。もしanacronを使っていない場合は、次のセクションEditing crontabsに進んでください。
anacronユーザは/etc/anacrontabを編集します。このファイルは4つのフィードを持っています。それぞれ「何日毎に実行するか」、「anacron実行の何分後にジョブを実行するか」、「ジョブの名前」、「ジョブの実行コマンド」です。
例えば、echo "I like anacron"を5日毎に、かつanacronがスタートしてから10分後に実行したい場合、次を入力してください。
/etc/anacrontab5 10 wasting-time /bin/echo "I like anacron"
anacronはanacrontabファイルに記載のすべてのジョブを完了後、終了します。これらのジョブが毎日実行されるかどうかを確認するためにcronデーモンが使用されます。次のセクションの最後に、これがどのように扱われるかを記載します。
crontabの編集
現実的に、ユーザーがどれぐらいcronを好きかをシステムに逐一報告させることを希望するユーザーはいないでしょう。次のステップとして、上記のコマンドリストの消去コマンドに相当するものを使用して、これまで使用したサンプルのcrontabを消去しましょう。消去した後はリストコマンドを使用して、cronジョブがすでに動作していないことを確認しましょう。
root #crontab -d
root #crontab -lcrontab -lでcronジョブは出力されないはずです。もしcronジョブが残っている場合、crontabの消去に失敗しています。その場合はシステムのcronパッケージに適した消去コマンドを使用してるかどうか確認してください。
これでクリーンな状態になりました。何か役に立つものをroot crontabに追加しましょう。多くの場合、mlocateを正しく動作させるために週単位でupdatedbを動かすでしょう。システムのcrontabに追加する場合、以下のようにcrons.cronを変更します。
22 2 * * 1 /usr/bin/updatedb
この例では、cronは毎週月曜朝の午前2時22分にupdatedbを起動します。適切な新規作成コマンドを上のコマンドリストから選択、実行してください。実行後、もう一度リストをチェックしましょう。
root #crontab crons.cron
root #crontab -lそれでは例として、Portageツリーを最新の状態に保つためにemerge --syncを毎日実行させるとしましょう。これはcrons.cronを編集し、上の例で示したようにcrontab crons.cronを実行する、もしくは上のコマンドリストの編集コマンドでスケジュールできます。後者はcrons.cron等の外部ファイルを使用せずにcrontabを直接編集することができます。
root #crontab -eこのコマンドはユーザーのcrontabをエディターで開きます。例えばemerge --syncを毎日午前6時30分に実行したい場合、crontabを以下のようにしてください。
22 2 * * 1 /usr/bin/updatedb
30 6 * * * /usr/bin/emerge --sync
## (anacronを使う場合は以下を加えてください)
30 7 * * * /usr/sbin/anacron -s
ジョブがスケジュールされたことを今一度確認するため、前述の例のようにcronジョブのリストを確認してください。もし期待しているものが全て表示された場合、ロックンロールの準備OKです。
cronbaseを使う
最初に述べたように、すべてのcronパッケージはsys-process/cronbaseに依存しています。このcronbaseパッケージは/etc/cron.{hourly,daily,weekly,monthly}と、run-cronsと呼ばれるスクリプトを生成します。デフォルトの/etc/crontabは以下のようになっていることに注意してください。
*/15 * * * * test -x /usr/sbin/run-crons && /usr/sbin/run-crons
0 * * * * rm -f /var/spool/cron/lastrun/cron.hourly
0 3 * * * rm -f /var/spool/cron/lastrun/cron.daily
15 4 * * 6 rm -f /var/spool/cron/lastrun/cron.weekly
30 5 1 * * rm -f /var/spool/cron/lastrun/cron.monthly
このファイルの詳細に立ち入るのはやめて、これらのコマンドは毎時、毎日、毎週、毎月スクリプトを実行するものとしましょう。cronジョブをスケジューリングするためのこの方法にはいくつかの重要なメリットがあります。
- これらのジョブがスケジュールされた時刻にコンピューターがオフだったとしても、再起動後にジョブは実行されます。
- パッケージのメンテナーにとって、明確に定義された場所にスクリプトを設置することは容易です。
- 管理者はcronジョブとcrontabがどこに保存されているか、正確に知ることが可能です。これにより、これらシステム構成物のバックアップおよびリストアが容易になります。
cronie、bronは自動的に/etc/crontabを読み込みます。一方、dcronとfcronは自動的には読み込みません。この点についてはSystem crontabセクションを熟読してください。
anacronを使う
先に記述したとおり、anacronは(ほとんどのデスクトップインストールがそうであるように)連続稼働しないシステムで使用されます。anacronのデフォルトの設定ファイルは/etc/anacrontabであり、通常は以下のようになります。
/etc/anacrontabSHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# フォーマット: 間隔 遅延 ジョブ識別子 コマンド
1 5 cron.daily run-parts /etc/cron.daily
7 10 cron.weekly run-parts /etc/cron.weekly
30 15 cron.monthly run-parts /etc/cron.monthly
anacrontabと他の一般的なcrontabとの違いは、anacronはジョブをスケジュールするにあたり、ランとランの間の時間間隔のみ設定し、固定した日時を指定しないことです。anacron起動時、anacronは/var/spool/anacronの内容をチェックして、最後のランから期限が切れたエントリーがないかどうか計算します。もしこのようなエントリが存在した場合、そのコマンドは再度起動されます。
最後の留意点として、システムにインストールされた他のcronとオーバーラップするエントリはコメントアウトしなければなりません。例えば以下のvixie-cronのcrontabはその例です。
/etc/crontab# for cronie
# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly
59 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly
#9 3 * * * root rm -f /var/spool/cron/lastrun/cron.daily
#19 4 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly
#29 5 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly
#*/10 * * * * root test -x /usr/sbin/run-crons && /usr/sbin/run-crons
@hourly root test ! -e /var/spool/cron/lastrun/cron.hourly && touch /var/spool/cron/lastrun/cron.hourly && run-parts --report /etc/cron.hourly
オーバーラップをコメントアウトしない場合、日、週、月の部分は、cronデーモンとanacronによって異なる時間に実行されます。これにより二重にジョブが実行されるかもしれません。
トラブルシューティング
cronが正しく動作しない場合、以下のチェックリストが役に立つかもしれません。
個々のcronパッケージは互いに異なり、機能的にも大きな幅を持っていることを覚えておいてください。使用しているcronデーモンにあわせて、crontab、fcrontab、anacrontab等のmanページをよく理解してください。
cronは起動していますか?
cronが起動しているかどうかを検証するため、cronがプロセスリストに存在しているかどうかを確認してください。
user $ps ax | grep cron'/var/spool/cron/crontabs' is not a directory
ユーザが "cron" グループに属しているか確認してください。グループの変更を反映させるために、ログアウトして再度ログインするのを忘れないでください。これでうまくいかない場合は、ユーザ名が /etc/cron.allow にあるか確認してください。これでもうまくいかない場合は、crontab を suid root に設定してください。
root #chmod u+s /usr/bin/crontab cronは動作していますか?
次を試してみてください。
* * * * * /bin/echo "foobar" >> /tmp/file_you_own
上記を実施後、/tmp/file_you_own が定期的に更新されているか確認してください。
そのコマンドは動作していますか?
同様に、標準エラー出力もリダイレクトしてみましょう。
* * * * * /bin/echo "foobar" >> /tmp/file_you_own 2>&1
cronはジョブを起動していますか?
cronのログを確認してください。通常、エラーは/var/log/cron.logもしくは/var/log/messagesに記録されます。
dead.letterはありますか?
通常、cronは何か問題が発生した時はメールを送付します。メールが届いていないか、もしくは~/dead.letterが生成されていないか確認してください。
なぜcronメールが送信されないのですか?
cronからメールを受信するためには、有効なMTAのセットアップが行われていなければなりません。これはvirtual/mtaのどのようなパッケージからも提供されます。
cron のメールがローカルにのみ送信され、完全に構成されたメールサーバーを経由しない場合には、各自の MTA を提供するパッケージで mbox use フラグをセットすることで、そのシステムで mbox (/var/spool/mail) メールを使用することができます。
外部資料
The following people contributed to the original document: Eric Brown, Xavier Neys,
Editors: please do not add yourself here. Contributions are recorded on each article's associated history page, this list is only present to preserve authorship information, as wiki history does not allow for any external attribution.