Cron

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Cron and the translation is 100% complete.
Resources

このガイドでは、Gentoo Linux における cron デーモンのセットアップと利用方法を説明します。

cronの基礎

cronとは何か

cronはcrontabコマンドからの入力に基づいてスケジュールされたタスクを起動するためのデーモンです。cronは1分毎に起床し、ユーザのcrontabに実行すべきcronジョブがあるかどうかチェックします。

メモ
crontab は cron ジョブリストの名前であると同時に、このリストを編集するためのコマンド名でもあることに注意してください。
メモ
systemd init システムを使用しているなら、(ana)cron を置き換えるものとして (永続的) タイマーを利用できます。

デファクトのcron

Portageにはいくつかのcron実装があります。これらはすべてよく似たインタフェースを持っていて、crontabもしくはそれに類似したコマンドを使用します。また、連続稼働しないシステムのcronと協調して動作するanacronと呼ばれる関連ユーティリティもあります。

現在利用可能な全てのcronパッケージはsys-process/cronbaseに依存しています。技術的には、どのcronパッケージもこのパッケージに依存していません。しかし、このパッケージは大部分のユーザに有益でcronに似た機能を提供します。

cronを動作させる前に、適切なcron実装が選択されていなければなりません。

どのcronが適しているか?

メモ
Gentoo標準のcron実装をインストールするために、virtual/cronをemergeしてください。

cronie

cronie (sys-process/cronie) は、現在は時代遅れとなった vixie-cron の Fedora によるフォークで、現在も保守が続けられています。このため 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 のような機能を含んでいます。

sys-process/dcron の特徴

  • 高速、単純、不要な仕様がない。
  • crontab へのアクセスを、例えばcronグループに所属するユーザだけに制限することができる。つまり、外部機能に依存しない。

fcron

sys-process/fcron は vixie-cron と anacron の置き換えを意図しています。連続稼働しないシステムで動作できるよう設計されていて、いくつかの拡張機能を持っています。それは「ジョブがスタートするための条件設定」、「ジョブの直列化制御」、「ジョブに nice 値を付与する機能」、「システム起動時に動作するジョブのスケジュール」です。

sys-process/fcronの特徴

  • 連続稼働しないシステムで動作するように設計されています。つまり、システム停止中のため動作できなかったジョブを再起動後に実行できます。
  • 環境変数やその他多くのオプションをcrontabで設定できます。
  • 多くの新機能と共に、拡張されたcrontab記述をサポートします。
  • 各ユーザーはcron.allowcron.denyでアクセス制御可能なcrontabを持つことができます。

bcron

sys-process/bcron はセキュアなオペレーションを念頭に置いて設計された新しい cron システムです。これを実現するため、cron システムはいくつかのプログラムに分割され、それぞれが別のタスクに対して責任を持つことになりました。また、それらタスク間のコミュニケーションは厳格に制御されました。ユーザインターフェースは、よく似たシステム(例 vixie-cron)の単純な置き換えですが、内部の実装は大きく異なっています。

sys-process/bcronの特徴

  • 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 anacron

anacronをインストールした場合は、anacronをシステムのinitプロセスに確実に加えてください。

root #/etc/init.d/anacron start
root #rc-update add anacron default

anacronに関しては、通常initプロセスはありません。その代わり、anacronは別のcron実装を通して実行される必要があります。

cron の定義を通じて anacron を起動するのが1つの方法です。デフォルトでは、ほとんどの cron 実装が使用する、1時間毎に起動するスクリプトがインストールされます。これが当てはまらない場合でも、手動定義を通じて起動することはできます:

ファイル /etc/crontabcron定義からanacronを実行する
# anacronを10分毎に開始する
*/10 * * *  root  /usr/sbin/anacron
 
# 代わりに、anacronによって提供されているOanacronスクリプトを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.allowallows all usersを記述した状態であり、cronグループに所属しているユーザーはfcrontabにアクセスできます。
コード fcron.denyで全てのユーザーを拒否
all

もし、あるユーザー(ここで再度 larry を例にとります)が独自の cron ジョブをスケジュールしたい場合、次を /etc/fcron/fcron.allow に追加してください。

コード fcron.allowでユーザーlarryを許可
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 を追加します。

コード /etc/cron.allowでユーザwepyを許可
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.cron
メモ
echoコマンドの出力はリダイレクトしない限り見ることができません。

スケジュールされたcronジョブを確認するため、コマンドリストの"cronジョブの表示 "に記載されているコマンドを使用します。

root #crontab -l

crons.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/anacrontab
5 10 wasting-time /bin/echo "I like anacron"

anacronはanacrontabファイルに記載のすべてのジョブを完了後、終了します。これらのジョブが毎日実行されるかどうかを確認するためにcronデーモンが使用されます。次のセクションの最後に、これがどのように扱われるかを記載します。

crontabの編集

現実的に、ユーザーがどれぐらいcronを好きかをシステムに逐一報告させることを希望するユーザーはいないでしょう。次のステップとして、上記のコマンドリストの消去コマンドに相当するものを使用して、これまで使用したサンプルのcrontabを消去しましょう。消去した後はリストコマンドを使用して、cronジョブがすでに動作していないことを確認しましょう。

root #crontab -d
root #crontab -l

crontab -lでcronジョブは出力されないはずです。もしcronジョブが残っている場合、crontabの消去に失敗しています。その場合はシステムのcronパッケージに適した消去コマンドを使用してるかどうか確認してください。

これでクリーンな状態になりました。何か役に立つものをroot crontabに追加しましょう。多くの場合、mlocateを正しく動作させるために週単位でupdatedbを動かすでしょう。システムのcrontabに追加する場合、以下のようにcrons.cronを変更します。

コード 実際のcrontab
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を以下のようにしてください。

コード 実際の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は以下のようになっていることに注意してください。

コード デフォルトのシステム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/anacrontab
SHELL=/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

cronは動作していますか?

次を試してみてください。

コード cronが動作しているかどうかを確認するためのcrontab
* * * * * /bin/echo "foobar" >> /tmp/file_you_own

上記を実施後、/tmp/file_you_own が定期的に更新されているか確認してください。

そのコマンドは動作していますか?

同様に、標準エラー出力もリダイレクトしてみましょう。

コード アプリケーションの動作を確認するためのcrontab
* * * * * /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) メールを使用することができます。

外部資料

  • https://crontab.guru/
    This page is based on a document formerly found on our main website gentoo.org.
    The following people contributed to the original document: Eric Brown, Xavier Neys,
    They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.