cronは実行されるがスクリプトが失敗する原因と確認手順
このページの目的
cron自体ではなく、呼び出されたコマンドやスクリプトの失敗を調べます。最終的なゴールは、同じ実行ユーザー・最小環境で失敗を再現し、PATH、相対パス、権限、環境変数のどこに差があるかを特定することです。
最初にやること
最初に標準出力と標準エラーをファイルへ保存し、cronと同じユーザー・最小環境で手動実行します。ログインシェルで成功するかどうかだけでは判断しません。
このページの対象:このページは「cronはジョブを呼び出したが、処理結果が失敗している」場合が対象です。予定時刻に実行記録そのものがない場合は、cronが実行されないガイドを先に確認してください。
cron設定を作成・確認
実行時刻とコマンドを入力し、crontab形式、実行ユーザー、パス、ログ出力の注意点を確認できます。
最初に失敗を再現できる状態にする
調査前に、エラーを消さずに残せる形へ変更します。
/absolute/path/job.sh >> /var/log/example/job.log 2>&1
- 手動でも失敗する:スクリプト、引数、権限、依存先を確認
- ログインシェルでは成功する:PATH、HOME、作業ディレクトリ、環境変数の差を確認
- cronだけ出力先へ書けない:実行ユーザーと親ディレクトリ権限を確認
よくある表示・症状から原因を絞る
表示された文言は原因そのものではなく、確認範囲を絞る手掛かりです。「考えられる原因」と「最初の確認方法」を対応させて確認します。
| エラー・症状 | 考えられる原因 | 最初の確認方法 |
|---|---|---|
command not found | cronのPATHにコマンドが含まれない、またはコマンド名が誤っている | command -v で実体を確認し、絶対パスで実行 |
Permission denied / cannot create ... | スクリプトの実行権限不足、または出力先・親ディレクトリへの権限不足 | id、namei -l、ls -ld で実行ユーザーと権限を確認 |
No such file or directory | 相対パス、作業ディレクトリ、参照ファイルの場所がcron環境と合っていない | pwdを記録し、使用パスを絶対パスへ置換して確認 |
bad interpreter: No such file or directory | shebangのパス誤り、またはCRLF改行でインタープリタ名が崩れている | head -1、file、sed -n l で先頭行と改行コードを確認 |
ModuleNotFoundError / command not found: python | 想定したPython・仮想環境が使われていない | Python実行ファイルの絶対パスと、その環境のpip一覧を確認 |
TERM environment variable not set | スクリプトがTTYや対話端末を前提にしている | cronと同じ非対話環境で実行し、TTY依存処理を特定 |
exit status 1 など非0終了 | スクリプトまたは呼出先アプリ内部で処理が失敗した | 終了コードと直前の標準エラー・アプリログを確認 |
原因を切り分ける確認手順
実行ユーザーを確認する
crontab -l sudo crontab -u appuser -lユーザーcrontab、rootのcrontab、
/etc/cron.dでは実行主体が異なります。同じユーザーで手動実行する
sudo -u appuser env -i PATH=/usr/bin:/bin HOME=/home/appuser /absolute/path/job.sh空に近い環境で実行し、ログインシェルでのみ定義される変数やaliasへの依存を確認します。
相対パスと作業ディレクトリを確認する
grep -nE '(^|[^/])\./|cd |pwd' /absolute/path/job.sh namei -l /absolute/path/job.shcronの作業ディレクトリを前提にせず、スクリプト冒頭で
cdするか絶対パスを使います。環境変数と秘密情報を確認する
sudo -u appuser env -i PATH=/usr/bin:/bin HOME=/home/appuser env sudo -u appuser test -r /path/to/envfile && echo readable.profileや対話シェルで読み込む設定はcronでは自動読込されません。終了コードと出力先権限を確認する
sudo -u appuser /absolute/path/job.sh echo $? namei -l /var/log/example/job.logログ、ロックファイル、一時ファイル、出力ディレクトリへの書込み権限を確認します。
確認結果から次の対応を決める
| 結果 | 主な対応 |
|---|---|
| command not found | 絶対パスを使うか、crontab内でPATHを明示します。 |
| No such file or directory | 相対パス、作業ディレクトリ、改行コード、shebangを確認します。 |
| Permission denied | スクリプト、親ディレクトリ、出力先、SELinuxを確認します。 |
| 手動では成功、cronだけ失敗 | 環境変数、HOME、PATH、TTY依存、認証情報を比較します。 |
この症状で多い原因
- ログイン時のPATHや環境変数を前提にしている
- 相対パスや現在ディレクトリに依存している
- 実行ユーザーが想定と違う
- shebangの実行ファイルが存在しない
- 出力先・ロックファイル・一時ディレクトリに書けない
- 対話入力、TTY、SSHエージェントなどを必要としている
再発防止
- コマンド・スクリプト・入出力先を絶対パスにする
- 実行ユーザーと必要な環境変数を設計書に明記する
- 標準出力・標準エラーと終了コードを記録する
- 二重実行が困る処理はロックを設ける
- 本番登録前に最小環境で手動実行する
cronでPATHが通らない原因と対策では、PATHとログイン環境の違いを詳しく確認できます。