


まずはcronの仕様をおさらいしておきましょう。cronは、Linux/Unix系のOSに標準で備わっている、コマンドやスクリプトを自動実行するためのプログラムです。システム管理者は、crontabという設定ファイルに、「いつ」「何を実行するか」を記述することで、簡単に処理の自動実行設定をすることができます。
cronへの指示は、以下のような決まった書式で記述します。
* * * * * 【実行コマンド】
0 3 * * * /usr/local/bin/backup.sh
5つのアスタリスクは、左から順に分・時・日・月・曜日を意味します。上記の例では、「毎月、毎日、曜日に関わらず、午前3時0分に、指定パスのバックアップスクリプトを実行」という設定になります。
設定の手軽さゆえに、cronは時に人為的なトラブルを引き起こすこともあります。ここでは、多くの情シス担当者が経験したであろう、起こりがちな事件を3つ見ていきましょう。
サーバーのリソースを使う重いバッチ処理は、深夜に設定することが多いものです。A社の新任の担当者は、ある新しいバッチを朝方の4時に設定しました。ところが朝出社してみると、まだバッチ処置が終わっていなかったのです。ログにも原因が見当たらず、分かったことはなぜか毎朝4時15分に、サーバーに謎の負荷がかかっている、ということだけでした。
新任の担当者は困り果て、念のためにとcrontabの設定を確認しました。
すると、crontabの中に、忘れ去られた一行を発見します。
15 4 * * * /path/to/old_report_generator.sh
数年前に退職した誰かが、現在はもう誰も参照していないレポートを自動作成するために設定したcronでした。これにより、サーバーに負荷がかかっていたのです。
忘れ去られた不要な処理が、誰も気づかぬまま実行され続ける。これぞcronにまつわるトラブルの代表的なものだといえるでしょう。
cronは月・日・時間・曜日を設定することができます。逆に言うと、年は設定できません。この仕様によって、1年前の時限爆弾が爆発することがあります。先ほどの例に続き、もうひとつ、忘れ去られたcronによるトラブルを紹介しましょう。
去年の10月17日、B社の開発チームは負荷テストのため、特定の月・日・時間にだけ実行されるcronを複数設定しました。
30 2 17 10 * /path/to/heavy_load_test_A.sh
31 2 17 10 * /path/to/heavy_load_test_B.sh
テストは無事終わりましたが、担当者はそのcronとテスト処理を消し忘れていました。そして1年後の10月17日、午前2時30分。忘れ去られたテストジョブが、再び実行されたのです。続けざまに起動した複数の高負荷処理に耐えきれず、サーバーはダウン。深夜の障害対応に追われた管理者が原因を突き止めた時、そこに残されていたのは1年前のタイムスタンプが押された、恐ろしい時限爆弾だったのでした。
最後に、トラブルではなく思いがけずcronに救われた事件をご紹介します。
週末に起きた、C社の予期せぬデータセンターの電源トラブル。週明けの月曜、多くの管理者がシステムの復旧に追われる中、たったひとつのサーバーだけは、何事もなかったかのように正常にサービスを再開していました。その秘密は、前任者によってcrontabにそっと仕込まれていた一行でした。
@reboot /path/to/critical_service_check.sh
@rebootという記述は、「時刻に関係なく、サーバーが起動した直後に一度だけこのコマンドを実行」という意味です。電源トラブル後、サーバーが再起動した際、cronはこの命令に従い、指定された /path/to/critical_service_check.sh というシェルスクリプトを実行しました。このシェルの中身は、重要なサービスの稼働状況を確認し、起動していなければ起動する、という内容のシェルでした。
このスクリプトがサーバー起動時に自動で実行された結果、必要なサービスがすべて自動で起動し、正常な状態に復旧していたのです。
ここまで、cronにまつわるトラブルを紹介してきましたが、cronは本来、情シスの頼れる相棒です。cronは単なるスクリプトのスケジューラーというだけでなく、Linux/Unixのさまざまなツールと組み合わせることで、多彩な働きをさせることもできます。ここでは、日々の業務に役立つcronの職人芸を3つご紹介します。
「昨日のディレクトリの状態を毎日バックアップしておきたい。でも、そのためにわざわざスクリプトは書きたくない」そんな要望を叶えてくれるcronを紹介します。
0 1 * * * tar czf /var/backups/www_$(date +\%Y\%m\%d).tar.gz /var/www/html
この一行を仕込んでおくだけで、毎日午前1時に、日付入りのバックアップファイルが自動で生成され続けます。$(…)というコマンド置換でファイル名に日付を埋め込み、cronの特殊文字である%を\でエスケープするのがポイントです。
大事なプロセスがたまに落ちていてトラブルになってしまう。そんな時もcronの出番です。cronで定期的にプロセスをチェックし、もし停止していたら再起動してもらう、という自己復旧の仕組みが作れます。
* * * * * pgrep -f ‘my_app.py’ >/dev/null || /usr/bin/python3 /path/to/my_app.py &
||(OR演算子)を使い、「左のpgrepコマンドが失敗したら(=プロセスがいないなら)、右の起動コマンドを実行せよ」という一行です。>/dev/nullで正常時の出力を捨てることで、余計な通知が飛ばないようにするのも一工夫です。
最後の職人芸を説明する前に、cronの恐ろしい罠を紹介しましょう。
crontabを編集する時には、「crontab -e」と入力しますよね。 では、キーボードに目を落としてみてください。eの隣には、rのキーがあります。
もし、タイプミスで「crontab -r」と入力してしまったら……。 -rは”reload”や”read”の略ではありません。removeのrです。
うっかり「crontab -r」と入力し、Enterキーを押してしまうと、crontabに書かれた設定は、一瞬ですべて削除されます。恐ろしい事実ですが、実際にこの罠にはまり、青ざめたことのある人は少なくないのです。
そこで、この悲劇から身を守る職人芸として、cronに自分自身のバックアップを取らせる方法を紹介します。
5 2 * * * crontab -l > /home/your_user/.crontab.bak
この設定により、毎日午前2時5分に、現在のcrontabの設定内容を-lオプションでリスト表示し、その結果を>(リダイレクト)を使ってホームディレクトリのバックアップファイルに上書き保存します。この一行をcrontabの末尾に書き込んでおくだけで、万一のタイプミスの際も安心です。

crontab -lで表示される一行一行。そこには、過去の管理者の工夫や願いだけでなく、時限爆弾が刻まれていることがあります。つい気軽に設定してしまうcronですが、定期的に見直しをして、不要な設定は削除するように気を付けましょう!
この機会に、ぜひご自身の管理するサーバーのcrontabをチェックしてみてください。もしかしたら自社のサーバーにも、怪しげな1行が残されているかもしれませんよ……。

木曜日の夕方に仕事で疲れた脳みそをリフレッシュしたいとき、一人でゆっくりしたい夜、ちょっとした空き時間に、気軽に「つまめる」ソースコードの話題をお届けします。
まるで隠れ家バーでマスターが語るウンチクのように、普段は見過ごしがちなコードの奥深さや、思わず「へぇ〜!」と唸るようなユニークなアイデア、クスッと笑える小ネタを、ソースコードの世界を熟知した「情シスのじかん」がご紹介します。
コードを書くのが大好きなエンジニアさんも、ソースコードはちょっと苦手…という情シス部門の方も、この特集を読めば、きっとソースコードの新たな一面を発見できるはず。
業務効率化のヒントになるTipsや、セキュリティ対策に役立つ情報も盛りだくさん。
さあ、あなたも「おつまみとしてのソースコード」で、技術の世界をもっと身近に、もっと楽しく感じてみませんか?
本特集はこちら30秒で理解!フォローして『1日1記事』インプットしよう!