この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
SE時代の2003年頃、客先のLinuxサーバーを管理していたときのことです。前日の深夜0時に実行されるはずだった定期バックアップが動いていないと気づいたのは、翌朝の作業確認中でした。バックアップファイルのタイムスタンプが昨日のまま止まっています。「設定は変えていない。一昨日まで動いていた。なぜだ。」と3時間近く格闘した末に原因が判明したとき、思わず苦笑いが漏れました。
この記事では、20年以上サーバーを運用してきた経験から、あの日の失敗が教えてくれた「cronが動かないときに最初に疑うべき3つのポイント」についてお話しします。
この記事のポイント
・cronが動かない第一の原因は環境変数(PATH)がターミナルと違うこと
・スクリプトに実行権限(chmod +x)が付いているか必ず確認する
・/var/log/cronのログで「実行されたか」という事実を最初に確認する
・cron設定後は必ず1分刻みのテスト実行でログ確認するのが鉄則
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
「設定は正しいはず」という思い込みが3時間を奪った
cronを疑い始めたとき、私がまず確認したのはcrontabの設定でした。# crontab -l の出力(当時の設定・ホスト名はマスク済み) 0 0 * * * /home/admin/backup.sh >> /var/log/backup.log 2>&1
3時間の間に私が確認したことは次の3つです。
・crontabの設定内容を3回見直した
・サーバーの時刻(date コマンド)を確認した
・cronデーモン(crond)が動いているか確認した
crondは問題なく起動していました。サーバーの時刻もあっていました。設定の書き方も文法的に正しかった。しかし気づかなかった落とし穴が3つあったのです。
cronが動かない本当の理由|SE時代に踏み抜いた3つの落とし穴
1. 環境変数(PATH)がターミナルと全く違う
cronが実行するスクリプトの環境変数(PATH)は、ターミナルでログインしたときとは別物です。これが3時間格闘した原因の一つでした。ターミナルでは ~/.bash_profile や /etc/profile によって /usr/local/bin などにパスが通っていますが、cronの実行環境でのPATHは最小限しか設定されていません。
# ターミナルで確認したPATH(ログイン環境) # echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin # cron実行環境でのPATH(デフォルト・非常に短い) /usr/bin:/bin
セミナーで3,100名以上を指導してきた中で、この環境変数の問題はcronでハマるケースの中で最も多い原因です。受講生の方が「cronが動かない」と言ってくれるとき、まず最初にこのPATHの問題を疑うようにしています。
解決策は2つあります。どちらも実務でよく使う方法です。
・スクリプトの先頭でPATHを明示的に設定する
・コマンドをすべてフルパスで記述する
#!/bin/bash # 方法1:スクリプト先頭でPATHを設定する PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin export PATH # 方法2:コマンドをフルパスで書く(例:rsyncの場合) /usr/bin/rsync -az /home/admin/data/ /backup/data/
2. スクリプトに実行権限が付いていなかった
cronで実行するシェルスクリプトに、実行権限(chmod +x)を付けることを忘れていたのが2つ目の落とし穴でした。ターミナルから手動で動かすときは `bash /home/admin/backup.sh` と呼び出していたので実行権限がなくても動いていました。しかしcrontabには `/home/admin/backup.sh` と直接パスを書いていたため、cronが実行しようとするとPermission deniedで失敗していたのです。
# 権限の確認(実行権限がない状態) # ls -l /home/admin/backup.sh -rw-r--r-- 1 admin admin 512 3月 15 09:23 backup.sh # ↑ 先頭の3桁が rw- で x がない = 実行権限なし # 実行権限を付与する # chmod +x /home/admin/backup.sh # 確認 # ls -l /home/admin/backup.sh -rwxr-xr-x 1 admin admin 512 3月 15 09:23 backup.sh # ↑ x が付いた = 実行権限あり
3. cronのログを最初から確認していなかった
3時間格闘した中で最も反省しているのが、cronのログを最初から確認しなかったことです。「cronは実行されているはずだ」という思い込みがあったため、ログ確認を後回しにしていました。しかし実際には cronが実行しようとしてエラーになっていたのです。ログを最初に見ていれば15分で解決できていたはずでした。
cronの実行記録は /var/log/cron(CentOS/RHEL系)に残ります。
# /var/log/cronの直近の記録を確認する(ホスト名はマスク済み) # tail -20 /var/log/cron Mar 16 00:00:01 srv-xx CROND[4821]: (admin) CMD (/home/admin/backup.sh >> /var/log/backup.log 2>&1) Mar 16 00:00:01 srv-xx CROND[4822]: (admin) CMD failed: backup.sh: /usr/bin/rsync: No such file or directory Mar 17 00:00:01 srv-xx CROND[5103]: (admin) CMD (/home/admin/backup.sh >> /var/log/backup.log 2>&1) Mar 17 00:00:01 srv-xx CROND[5104]: (admin) CMD failed: backup.sh: /usr/bin/rsync: No such file or directory
受講生からよく聞かれる質問が「cronが動かないときどこから調べればいいですか?」です。私の答えは常に同じです。「まず /var/log/cron を tail -20 で見てください。cronが実行されたかどうかという事実を、まず確認することが大切です。」
現役講師が教えるcron設定後の確認3ステップ
あの失敗から20年以上が経ちますが、今もcronを設定したときに必ず実施している確認手順があります。受講生にも毎回お伝えしている3ステップです。1. crontabの内容を保存後すぐ確認する
crontab -e で設定を保存したら、すぐに crontab -l で設定が反映されているか目視確認します。書き方のミスや意図しない削除が起きていないかを最終確認する習慣です。# crontab -l で設定内容を確認する # crontab -l 0 0 * * * /home/admin/backup.sh >> /var/log/backup.log 2>&1
2. テスト用に1分刻みのcronを設定してログで動作確認する
本番のcronを設定する前に、まずテスト用として「毎分実行」のcronを設定して/var/log/cronに記録が出るか確認します。実際に記録が出ていればcron自体は動いていることが確認できます。# テスト用:毎分実行するcronを設定する(動作確認後に必ず削除する) * * * * * echo "cron-test" >> /tmp/cron-test.log # 1分後にログを確認する # tail -5 /tmp/cron-test.log cron-test cron-test # ↑ 記録されていれば cron は正常に動作している # 確認が取れたらテスト用cronを削除する # crontab -e ← テスト行を削除する
3. 本番スクリプトの実行権限とPATHを確認してから登録する
本番のcronを登録する前に、スクリプト自体を単独実行してエラーが出ないか確認します。さらに、スクリプト先頭にPATHの明示的な設定と実行権限(chmod +x)が付いているかを確認してから登録するのが鉄則です。# 1. 実行権限の確認と付与 # ls -l /home/admin/backup.sh -rw-r--r-- 1 admin admin 512 Mar 15 09:23 backup.sh # chmod +x /home/admin/backup.sh # 2. スクリプトをcronと同じ環境(最小PATH)で動作確認する # env -i PATH=/usr/bin:/bin /home/admin/backup.sh # ↑ エラーが出なければcronでも動く可能性が高い # 3. スクリプト先頭でPATHが設定されているか確認する # head -5 /home/admin/backup.sh #!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin export PATH
本記事のまとめ
あの日の3時間の格闘を一言でまとめると、「cronが動かない原因のほとんどは、cronの実行環境を理解していないことにある」です。ターミナルでは動くのにcronでは動かない。その差のほとんどは環境変数・実行権限・ログ未確認の3点に集約されます。
| 症状 | まず確認すること |
|---|---|
| cronが実行されない(ログに記録がない) | crondの起動確認(systemctl status crond) |
| cronは実行されているがスクリプトが失敗する | /var/log/cronでエラーメッセージを確認 |
| 「command not found」エラー | スクリプト先頭でPATHを明示設定する |
| 「Permission denied」エラー | chmod +x でスクリプトに実行権限を付与 |
| 手動では動くがcronでは動かない | env -i PATH=/usr/bin:/bin スクリプトで動作確認 |
「cronは動く」という自信を、最初から正しい型で身につけませんか?
環境変数・実行権限・ログ確認——この3点を最初から体系的に学んでいれば、3時間の格闘は防げました。ネットの断片情報を拾い集めるより、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます