「動いてるつもり」が一番怖い|cronジョブの落とし穴と3つの対策

HOMEリナックスマスター.JP 公式ブログLinux学習ガイド > 「動いてるつもり」が一番怖い|cronジョブの落とし穴と3つの対策

図解60p「Linuxサーバー構築入門マニュアル」無料
登録10秒/自動返信でDL/合わなければ解除3秒
リナックスマスター.JPの宮崎智広です。
いつもありがとうございます。

「cronでバックアップを自動化したけど、本当にちゃんと動いているのか不安...」
「cronジョブが失敗していたのに、誰も気づけなかった」

こういう経験、ありませんか?

実は、cronには致命的な弱点があります。それは「起動は保証するけど、成功は保証しない」ということです。

この記事では、15年以上サーバーを運用してきた経験から、cronジョブの「動いてるつもり」がなぜ一番怖いのか、そしてその落とし穴を防ぐための3つの対策を具体的なスクリプト付きで解説します。

cron-job-otoshiana-taisaku.jpg

私が経験した「2ヶ月間バックアップが取れていなかった」事件


新人SEの頃の話です。

ある日、上司から「バックアップから戻してくれ」と言われました。
保存先のディレクトリを開いた瞬間、自分の目を疑いました。

最新のバックアップファイルの日付が、2ヶ月前だったんです。

毎晩3時にバックアップを取るcronジョブを、ちゃんと設定したはずでした。設定した日に動作確認もしました。

でも、2ヶ月前のディスク構成変更で、保存先のパスが変わっていたんです。

スクリプトは毎晩起動していました。毎晩エラーを吐いていました。でも、誰もそのエラーに気づかなかった。

幸いにも、手動で取っていた古いバックアップが残っていて、なんとか復旧できました。しかし、あの時の冷や汗は今でも覚えています。

この経験から学んだことは1つ。

「動いてるつもり」が一番怖い、ということです。

サービスが止まれば、すぐ気づけます。監視アラートが鳴れば、対応できます。
でもcronジョブの失敗は違います。バックアップが必要になった時、レポートを求められた時、ログの整理が必要になった時。「結果を使う日」に初めて「動いてなかった」と気づくんです。

しかも、そういう時はたいてい緊急事態です。一番困っている時に、頼みの綱が切れていたと分かる。

セミナーで3,100名以上を指導してきた中でも、「cronジョブが知らない間に止まっていた」という相談は本当に多いです。

cronの「弱点」を正しく理解する


まず、cronが何を保証して何を保証しないのか、正確に理解しておきましょう。

cronの仕事は「指定した時間に、指定したコマンドを起動する」。これだけです。

・コマンドが正常に終了したか
・ファイルがちゃんと生成されたか
・期待通りの結果になったか

これらはすべてcronの管轄外です。

cronのログ(/var/log/cron)を見ても、「起動した」という記録しか残りません。実際に確認してみましょう。

# cronログで直近の実行記録を確認する sudo grep CRON /var/log/cron | tail -5 # 出力例 Mar 12 03:00:01 server01 CROND[12345]: (root) CMD (/root/backup.sh) Mar 12 03:00:01 server01 CROND[12346]: (root) CMD (/root/cleanup.sh)

この出力から分かるのは「何時何分に、どのユーザーが、何のコマンドを起動したか」だけです。
backup.shが成功したのか失敗したのかは、一切記録されていません。

だから、cronに任せっぱなしにすると「動いてるつもり」の状態になるんです。

では、どうすればいいのか。対策は3つあります。

対策1|ログに残す


1. リダイレクトの基本(>> と 2>&1)


まず最低限やるべきことは、cronジョブの出力をログファイルに残すことです。

crontabの設定で、コマンドの末尾にリダイレクト記号を追加します。

# NG:出力を残さない(デフォルトの状態) 0 3 * * * /root/backup.sh # OK:出力をログファイルに残す 0 3 * * * /root/backup.sh >> /var/log/backup.log 2>&1

ポイントは末尾の「>> /var/log/backup.log 2>&1」です。

>> : ログファイルに追記する(> だと毎回上書きされてしまう)
2>&1 : エラー出力(2)を標準出力(1)と同じ場所に流す

「2>&1」がないと、正常時のメッセージは残るのに、肝心のエラーメッセージが消えてしまいます。
cronジョブのログには必ず「2>&1」を付けてください。これがないと、失敗した時に何が起きたか追えません。

2. 実践例:バックアップスクリプトにログを追加


実際のバックアップスクリプトを例に、ログ出力を組み込む方法を見てみましょう。

#!/bin/bash # バックアップスクリプト(ログ出力付き) LOGFILE="/var/log/backup.log" BACKUP_DIR="/backup/db" DATE=$(date +%Y%m%d_%H%M%S) echo "===== バックアップ開始: $(date) =====" >> "$LOGFILE" # データベースのバックアップを取得 /usr/bin/pg_dump mydb > "${BACKUP_DIR}/mydb_${DATE}.sql" 2>> "$LOGFILE" if [ $? -eq 0 ]; then echo "[SUCCESS] バックアップ完了: mydb_${DATE}.sql" >> "$LOGFILE" else echo "[ERROR] バックアップ失敗" >> "$LOGFILE" fi echo "===== バックアップ終了: $(date) =====" >> "$LOGFILE"

このスクリプトを使えば、/var/log/backup.log を見るだけで「いつ実行されて、成功したか失敗したか」が一目で分かります。

ただし、ログを残すだけでは足りません。

なぜなら、ログは「見に行かないと気づけない」からです。「毎日ログを確認しよう」と決めても、1週間もすれば見なくなります。これは人間の性質として仕方のないことです。

だから、次の対策が必要になります。

対策2|失敗時に通知する


1. exit codeでチェックする仕組み


Linuxのコマンドは、実行結果を「終了コード(exit code)」で返します。

0 : 成功
0以外 : 失敗(1, 2, 127など、エラーの種類によって異なる)

この終了コードを使って、「失敗した時だけ通知を飛ばす」仕組みを作ります。

考え方はシンプルです。毎日「成功しました」と通知されても、すぐに読まなくなります。「失敗した時だけ」通知する。これだけで「動いてるつもり」問題の大部分を防げます。

2. メール通知スクリプトの例


実際のスクリプト例を見てみましょう。

#!/bin/bash # バックアップスクリプト(失敗時メール通知付き) LOGFILE="/var/log/backup.log" BACKUP_DIR="/backup/db" DATE=$(date +%Y%m%d_%H%M%S) ADMIN_MAIL="admin@example.com" echo "===== バックアップ開始: $(date) =====" >> "$LOGFILE" # データベースのバックアップを取得 /usr/bin/pg_dump mydb > "${BACKUP_DIR}/mydb_${DATE}.sql" 2>> "$LOGFILE" if [ $? -ne 0 ]; then # 失敗時:ログに記録 + メール通知 echo "[ERROR] バックアップ失敗: $(date)" >> "$LOGFILE" echo "バックアップが失敗しました。 サーバー: $(hostname) 日時: $(date) ログ: $LOGFILE" | mail -s "[ERROR] バックアップ失敗 - $(hostname)" "$ADMIN_MAIL" else echo "[SUCCESS] バックアップ完了: mydb_${DATE}.sql" >> "$LOGFILE" fi

「$?」は直前のコマンドの終了コードです。「-ne 0」は「0ではない(=失敗)」という意味です。

このスクリプトなら、失敗した時だけメールが飛びます。「通知が来ない=正常」という状態を作れるので、日常的にログを確認する必要がなくなります。

メール送信には mail コマンド(mailx パッケージ)を使っています。サーバーにPostfixなどのMTAが設定されている必要があります。

対策3|週次サマリーで「ハートビート確認」


1. 定期的に「正常に動いているか」を確認する習慣


「失敗したら通知する」仕組みを作った。通知が来ない。よし、正常だな。

...本当にそうでしょうか。

・メールサーバーが止まっていたら?
・cronジョブ自体がそもそも起動しなくなっていたら?

「通知が来ない」理由が「成功しているから」ではなく「通知できない状態だから」というケースがあります。

これを防ぐのが「週次サマリー」です。週に1回だけ、「今週のバックアップはすべて成功しました」というサマリーメールを送ります。

#!/bin/bash # 週次バックアップサマリー(毎週月曜9時に実行) LOGFILE="/var/log/backup.log" ADMIN_MAIL="admin@example.com" # 過去7日間のログからSUCCESSとERRORの件数を集計 SUCCESS=$(grep -c "\[SUCCESS\]" "$LOGFILE" 2>/dev/null || echo 0) ERROR=$(grep -c "\[ERROR\]" "$LOGFILE" 2>/dev/null || echo 0) SUBJECT="[週次レポート] バックアップサマリー - $(hostname)" BODY="サーバー: $(hostname) 期間: $(date -d '7 days ago' +%Y/%m/%d) ~ $(date +%Y/%m/%d) 成功: ${SUCCESS}件 失敗: ${ERROR}件 このメールは週次の生存確認です。 このメール自体が届かなくなったら、通知の仕組みに問題が起きています。" echo "$BODY" | mail -s "$SUBJECT" "$ADMIN_MAIL"

このスクリプトをcrontabに登録します。

# crontab -e で以下を追加 # 毎週月曜の朝9時に週次サマリーを送信 0 9 * * 1 /root/weekly_summary.sh

毎日の成功通知は不要です。でも、週に1回の「生存確認」があると、通知の仕組み自体が生きているかまで確認できます。

「通知が来ない」のが「正常だから」なのか「壊れているから」なのか。この区別ができるかどうかで、運用の安心感がまったく変わりますよ。

私が現場でよく見かけるのが、失敗通知の仕組みは作ったのに、メールサーバーの設定変更で通知が届かなくなっていたケースです。週次サマリーがあれば「月曜にメールが来ない」時点で異常に気づけます。

よくある質問


Q. cronジョブが動いているかどうか、手っ取り早く確認する方法はありますか?


cronログを確認するのが一番手軽です。

# cronの実行ログを確認する sudo grep CRON /var/log/cron | tail -10

ここに実行記録があれば「起動はしている」ことが分かります。ただし、成功したかどうかは分からないので、ジョブのログファイル(>> で出力したファイル)も合わせて確認してください。

Q. mail コマンドが使えない環境ではどうすればいいですか?


mail コマンドが使えない場合は、curl を使ってSlackやChatworkなどのチャットツールに通知を送る方法があります。

# Slack Webhook を使った通知例 curl -s -X POST -H 'Content-type: application/json' \ --data '{"text":"[ERROR] バックアップ失敗 - サーバー名"}' \ https://hooks.slack.com/services/YOUR/WEBHOOK/URL

環境に合わせて通知先を選んでください。大事なのは「失敗に気づける仕組みがあること」です。手段は何でも構いません。

Q. cronジョブが多すぎて、どれにログや通知を入れるべきか判断できません


まずは「失敗した時の影響が大きいジョブ」から優先してください。

・バックアップ系のジョブ(データ消失に直結する)
・ログローテーション(ディスク容量に直結する)
・セキュリティ関連(脆弱性スキャン、証明書更新など)

すべてのジョブに一度に導入する必要はありません。影響度の高いものから順番に対策を入れていけば、運用は確実に安定していきます。

まとめ


対策 やること 効果
対策1:ログに残す コマンド末尾に >> /var/log/xxx.log 2>&1 を追加 「何が起きたか」を後から追える
対策2:失敗時に通知する スクリプト内で終了コード($?)を判定し、失敗時だけメール送信 ログを毎日見に行かなくても失敗に気づける
対策3:週次サマリー 週1回「今週の結果」をまとめて送信 通知の仕組み自体が生きているか確認できる

cronの「正しい設定方法」を体系的に学びませんか?

cronは便利ですが、正しく使わないと「動いてるつもり」の罠にはまります。運用の基本を体系的に学びましょう。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。


P.S
セミナーでは、cronの設定だけでなく、「運用で失敗しないための考え方」も実践的に学べます。構築して終わりではなく、その後の運用まで見据えた学習ができるのがセミナーの強みです。
【Linuxセミナー】リナックスマスタープロセミナー

[「とりあえず再起動」が危険な理由|プロのトラブル初動を現役講師が解説]
[Linuxサーバー構築の全体像|初心者が知っておくべき手順と現場のリアル]


無料プレゼント
図解60p「Linuxサーバー構築入門マニュアル」
独学で詰まる前に、“型(手順書)”で最初の環境構築をサクッと終わらせましょう。
登録10秒/自動返信でDL/合わなければ解除3秒
無料で受け取る ※メールアドレスだけでもOK(必須項目は最小限)

宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。


図解60pのLinux無料マニュアル
登録10秒/自動返信でDL
無料で受け取る