crontab スクリプトが動作しないのはなぜですか?

crontab スクリプトが動作しないのはなぜですか?

多くの場合、crontabスクリプトはスケジュールどおりに、または期待どおりに実行されません。それにはさまざまな理由があります。

  1. crontab の表記が間違っている
  2. 権限の問題
  3. 環境変数

crontabこのコミュニティ ウィキは、スクリプトが期待どおりに実行されない主な理由を集約することを目的としています。それぞれの理由を個別の回答に記入してください。

回答ごとに 1 つの理由 (実行されない理由の詳細) と、その理由に対する修正を記載してください。

cron 固有の問題のみを記述してください。たとえば、シェルからは期待どおりに実行されるが、cron では誤って実行されるコマンドなどです。

答え1

異なる環境

Cron は最小限の環境変数セットをジョブに渡します。違いを確認するには、次のようなダミージョブを追加します。

* * * * * env > /tmp/env.output

が作成されるのを待って/tmp/env.outputから、ジョブを再度削除します。次に、 の内容を通常のターミナルで実行/tmp/env.outputの出力と比較します。env

ここでよくある「落とし穴」は、環境変数が異なることです。おそらく、cron スクリプトは にあるPATHコマンドを使用していて、それをに追加したのではないでしょうか。cron はそのファイルからの を無視するため、スクリプトからの実行はcron で実行すると失敗しますが、ターミナルで実行すると機能します。 からの変数はcron ジョブに渡されますが、 などの cron が独自に設定する変数は渡されないことに注意してください。somecommand/opt/someApp/binPATH/etc/environmentPATHsomecommand/etc/environmentPATH

PATHこれを回避するには、スクリプトの先頭に独自の変数を設定するだけです。例:

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

代わりに、すべてのコマンドへの絶対パスを使用することを好む人もいます。私はそれをお勧めしません。スクリプトを別のシステムで実行したい場合、そのシステムではコマンドが である場合に何が起こるかを考えてみましょう。スクリプトの最初の行を少し編集するのではなく、スクリプト/opt/someAppv2.2/bin全体を に置き換えて確認する必要があります。/opt/someApp/bin/opt/someAppv2.2/bin

crontabファイルでPATH変数を設定することもできます。これはすべてのcronジョブに適用されます。例:

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

答え2

一番の注意点は、ファイルの最後に改行を追加するのを忘れた場合ですcrontab。言い換えると、crontab ファイルは空行で終わる必要があります。

以下は、この問題に関するマニュアル ページの関連セクションです (man crontab最後までスキップしてください)。

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

答え3

Cron デーモンが実行されていません。数か月前にこれで本当に失敗しました。

タイプ:

pgrep cron 

番号が表示されない場合 (つまり、cron のメイン PID)、cron は実行されていません。sudo /etc/init.d/cron startを使用して cron を開始できます。

編集: /etc/init.d から init スクリプトを呼び出すのではなく、サービスユーティリティを使用します。例:

sudo service cron start

編集: また、最近のLinuxではsystemctlを使うこともできます。

sudo systemctl start cron

答え4

多くの環境では、cron は を使用してコマンドを実行しますshが、多くの人は を使用すると想定していますbash

失敗したコマンドをテストまたは修正するための提案:

  • 次のコマンドを実行して、sh動作するかどうかを確認してください。

    sh -c "mycommand"
    
  • コマンドが bash で実行されるようにするには、コマンドを bash サブシェルでラップします。

    bash -c "mybashcommand"
    
  • crontab の先頭にシェルを設定して、cron にすべてのコマンドを bash で実行するように指示します。

    SHELL=/bin/bash
    
  • コマンドがスクリプトの場合は、スクリプトにシェバンが含まれていることを確認します。

    #!/bin/bash
    

関連情報