cron による定期実行のしくみ
決まった時刻や間隔でコマンドを自動実行したいときは cron を使います。cron は常駐しているデーモン(crond)が一定間隔で予定表を読み、時刻が来たコマンドを起動するしくみです。各ユーザは自分専用の予定表(crontab)を持ち、ログイン中でなくても処理が動きます。バックアップ・ログの整理・通知などの定例作業を人手なしで回せるのが利点です。
サーバを運用していると、「毎晩バックアップを取る」「1時間ごとに一時ファイルを掃除する」「月初に集計メールを送る」といった、決まったタイミングで自動的に走ってほしい作業が必ず出てきます。こうした定期実行を人手なしで回すための、Linuxにおける最も古くからある定番のしくみが cron です。読み方は「クロン」で、ギリシャ語の chronos(時間)に由来します。一度仕込んでおけば、あなたが寝ていても、ログアウトしていても、決めた時刻が来れば黙って処理が動きます。人間がやると忘れたり手順を間違えたりする定例作業を、機械に正確に肩代わりさせられるのが最大の価値です。サーバ運用の自動化を学ぶうえで、まず最初に身につけたい基礎がこの cron だと言ってよいでしょう。
cron の中心にいるのは crond(cron daemon)という常駐プログラムです。デーモンとは、画面を持たず背景でずっと動き続けるサービスのことで、crond はシステムが起動するとともに立ち上がり、以後ほぼ1分ごとに目を覚まして「いま実行すべき予定はないか」を確認します。その予定が書かれた表のことを crontab(cron table)と呼びます。crond は登録されている crontab を読み、各行に書かれた実行時刻と現在時刻を突き合わせ、一致した行のコマンドだけを起動します。つまり「1分ごとに予定表をめくり、時間が来たものを実行する受付係」が常駐している、とイメージすると分かりやすいでしょう。crond 自身が動いているかどうかは systemctl status crond(ディストリビューションによっては cron)で確認でき、止まっていればどんなに正しく予定を書いても実行されません。「登録したのに動かない」ときに最初に見るべき場所のひとつです。
ユーザごとの予定表と編集方法
cron の予定表は、システム全体で1つではなく、各ユーザが自分専用の crontab を持てるのが特徴です。user01 が登録した予定は user01 の権限で、root が登録した予定は root の権限で実行されます。これにより、一般ユーザが自分の作業だけを自動化したり、管理者がシステム全体の保守を仕込んだりを、互いに干渉せず行えます。自分の crontab を編集するには crontab -e を使います。これを実行するとエディタが開き、保存して閉じると内容が検証されて登録されます。登録済みの内容を確認するには crontab -l、まるごと削除するには crontab -r です。crontab -r は確認なしで全消去してしまうので、内容を見たくて -l(小文字のエル)と打つつもりが、隣の -r を押してすべて消す、という事故に注意してください。心配なら定期的に crontab -l > ~/crontab.bak のように現在の内容を控えておくと安全です。
編集時に開くエディタは EDITOR 環境変数で決まります。意図せず vi が開いて操作に困る、という初学者のつまずきが多いので、export EDITOR=nano のように普段使うエディタを指定しておくと安心です。なお、他人の crontab を扱うには管理者権限が必要で、root は crontab -u user01 -e のように -u で対象ユーザを指定して編集できます。誰が cron を使えるかは /etc/cron.allow と /etc/cron.deny で制御されており、環境によっては一般ユーザの利用が制限されていることもあります。
システム用の cron と /etc/cron.*
ユーザごとの crontab とは別に、システム全体で動かす定期処理のしくみもあります。/etc/crontab や /etc/cron.d/ 配下のファイルがそれで、これらは書式に「実行ユーザ」の列が1つ増えるのが個人用との違いです。アプリケーションが自分の定期処理を登録するときは、この /etc/cron.d/ にファイルを1つ置く形がよく使われます。さらに手軽な方法として、/etc/cron.daily/、/etc/cron.weekly/、/etc/cron.monthly/、/etc/cron.hourly/ というディレクトリが用意されており、ここに実行権を付けたスクリプトを置くだけで、それぞれ毎日・毎週・毎月・毎時に実行されます。細かい時刻指定が要らない定例処理なら、書式を覚えなくてもファイルを置くだけで済むので便利です。ログのローテーション(logrotate)など、OSが標準で用意する多くの定期処理も、このしくみで動いています。
ログと実行結果の受け取り方
cron で動かした処理は画面に結果が出ないため、「動いたのか動いていないのか分からない」状態になりがちです。crond は実行したことを /var/log/cron(ディストリビューションによっては journal)に記録するので、まずはここを見れば「起動された形跡」は追えます。ただしこのログに残るのは「起動したこと」だけで、ジョブの中身が成功したか失敗したかまでは分かりません。そこで重要になるのが、cron はジョブが標準出力や標準エラーに何か出力すると、その内容をそのユーザ宛のメールとして送ろうとする、という挙動です。メール配送が設定されていない環境では送れずに終わりますが、この性質を逆手に取り、コマンドの末尾に >> /var/log/myjob.log 2>&1 のように書いて、出力とエラーを自分でログファイルへ追記しておくのが定番の作法です。こうしておけば、後から「いつ・何が・どう失敗したか」を確実にたどれます。結果メールの宛先は、crontab の冒頭に MAILTO=you@example.com と書いて指定することもできます。
cron が向く場面・向かない場面
cron は「決まった周期で軽い処理を回す」のが得意です。一方で、1分より細かい間隔の実行はできない、電源が切れていた間に逃した実行は後から取り戻せない、依存関係(Aが終わってからB)は書けない、といった限界もあります。これらが問題になる場面では、後の項で扱う systemd timer や、1回だけの予約に向く at が選択肢になります。逆に言えば、毎日や毎時の定例処理のように要件が素直なら、cron はいまでも最短で仕込める手堅い選択肢です。まずは「定期実行といえば cron、その実体は crond が crontab を1分ごとに読んで動かしている」という全体像を押さえておけば、書式や応用といった各論の理解がぐっと早くなります。次の項では、その crontab に書く1行の書式を詳しく見ていきます。