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


525

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

  1. 間違ったcrontab表記
  2. 権限の問題
  3. 環境変数

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

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

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


12
crontab -ecronを有効にするには、閉じる必要があります。たとえば、vimを使用してファイルを編集し、:w書き込みに使用しますが、ジョブは終了するまでcronに追加されません。ですから、私:qも仕事が終わるまで見ません。
DutGRIFF

cronをデバッグする最良の方法は、syslogをチェックして問題を見つけることだと思います。
スニールクマール

私の場合、電子メールはSPAMフォルダに送られていたので、デバッグに何時間も費やす前に確認してください:D
almaruf

回答:


501

異なる環境

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

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

/tmp/env.output作成されるのを待ってから、ジョブを再度削除します。次に、の内容を通常の端末/tmp/env.outputでのenvrun の出力と比較します。

ここでよくある「落とし穴」は、PATH環境変数が異なることです。たぶん、あなたのcronスクリプトは、コマンド使用somecommandで見つかった/opt/someApp/binあなたが追加した、PATHでは/etc/environment?cronはPATHそのファイルから無視するためsomecommand、cronで実行するとスクリプトからの実行は失敗しますが、端末で実行すると動作します。からの変数/etc/environmentがcronジョブに渡されることに注意してくださいPATH

これを回避するに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

5
私はちょうどこのために落ちたと思う、そして最後に改行が...ダブルワミー。
WernerCD

6
+1のためにenv、私はそのコマンドを完全に忘れていて、PATHが機能していると思っていました。私の場合は実際にはまったく異なりました。
イズカタ

8
@pbrそのようなディレクトリが他の人に書き込み可能なままになっている場合、システムはすでに危険にさらされています。
ガイラ

6
@pbr sysadminは、ルートファイルシステムを意図せず削除する可能性があります。システム管理者が愚かな間違いを犯すのを防ぐことはできません。後方互換性のないインタープリターの新しいバージョンをインストールする場合は、それにもかかわらず破損が予想されます。それを処理するための正しい方法は、別のコマンドとしてインストールすることです。たとえば、pythonバージョン2.xがあり、python 3をインストールする場合、pythonではなくpython3としてインストールします。また、/ opt / someApp / binについては、なぜ一体全体に正しい許可/所有権がないのでしょうか?健全な管理者であれば、システムファイルの健全な許可/所有権を確保できます。
ガイラ

2
@pbr永遠に続けられるようです、はい。しかし、なぜPATHを使用するのが悪い考えなのか、まだわかりません。議論に適した媒体でこれについてさらに議論したい場合は、#ubuntuと#bashで、他のチャネルの中で、irc.freenode.net
geirha

336

私の一番の落とし穴:crontabファイルの最後に改行を追加するのを忘れた場合。つまり、crontabファイルは空行で終わる必要があります。

以下は、この問題に関するmanページの関連セクションです(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)

91
これは非常に素晴らしいことですが、なぜ長年のcronで修正されなかったのでしょうか?
カピエテリエル

2
Vixie cronで修正されるようです:man crontabUbuntu 10.10では、「cronではcrontabの各エントリが改行文字で終了する必要があります。crontabの最後のエントリに改行がない場合、cronはcrontab(少なくとも部分的に)が壊れていると見なしますインストールを拒否します。」(そして、終了日は2010年4月19日です。)
マリウスゲドミナス

19
@barrapontoこれは、実際には新しいテキストエディタのバグです。「改行」文字は行終端文字であると想定されているため、テキストファイルの最終行は、エディターに表示されない改行文字で終了することになっています。Viとvimはその文字を正しく使用します。cronは、新しいエディターが奇妙な動作を開始する前に構築されました。
イズカタ

6
crontabを使用しcrontab -eてcrontabを編集すると、保存を許可する前にファイルの構文がチェックされ、改行のチェックも含まれます。
トムハリソンJr 14

2
@ Chan-HoSuh、manページによると「cronはcrontabの各エントリが改行文字で終わることを必要とします。crontabの最後のエントリに改行がない場合、cronはcrontabを(少なくとも部分的に)壊れているとみなし、拒否しますインストールしてください。」この動作は、-eオプションを使用してcrontabを編集して保存するときに呼び出され、エディターから独立しています。
トム・ハリソンジュニア14年

139

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

タイプ:

pgrep cron 

番号が表示されない場合、cronは実行されていません。sudo /etc/init.d/cron startcronの起動に使用できます。

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

sudo service cron start

編集:また、現代のLinuxでsystemctlを使用することができます、例えば

sudo systemctl start cron

47
pgrepを見せてくれてありがとう。私はps -efを続けました| grep foo
ripper234

4
またpidof cron、crontabのように「cron」という単語が含まれる他のアプリケーションの結果を除外するwhichを使用することもできます。
ピチコス14年

奇妙なことに、これらすべてはcronが実行されていることを示すものを何も与えませんが、実行するsudo service cron startと、次のようになりますstart: Job is already running: cron
コリーン

1
service crond startその中心/ RHEL
スリハリカランス

91

スクリプトファイル名cron.d/cron.daily/cron.hourly/などは、(ドットを含むべきではありません.)、そうでない場合は、実行の部分は、それらをスキップします。

run-parts(8)を参照してください:

   If neither the --lsbsysinit option nor the --regex option is given then
   the names must consist entirely of upper and lower case  letters,  dig‐
   its, underscores, and hyphens.

   If  the  --lsbsysinit  option  is given, then the names must not end in
   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to
   one  or more of the following namespaces: the LANANA-assigned namespace
   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces
   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace
   (^[a-zA-Z0-9_-]+$).

あなたはcronスクリプトを持っているのであれば、backup.shanalyze-logs.plcron.daily/ディレクトリには、拡張子名を削除するために最善をしたいです。


10
これはバグではなく機能です。myscript.backup、myscript.original、myscript.rpm-newなどがmyscriptのすぐ横で実行されないようにします。
-pbr

@pbr:理にかなっています。run-parts --test(または--debug、理由を含めてスキップするファイルを出力するような別の想像上のオプションがあればデバッグに役立ちます。
Rabarberski

8
これが機能である場合、それは素晴らしいものではありません:(多くの人がファイル名にドットを使用しています(backup.shが最も一般的なものです)。実行を停止するスクリプトが必要な場合、最も論理的な方法は「cron.d」ディレクトリから削除します
MatuDuke

7
これは非常に悪い機能であり、事実上バグです。人々が意図したときにのみ実行されることを確認したい場合、特定のエンディング(「.list」や「.cron」など)を要求するのが一般的な方法です。「.bak」または「.temp」などの区切り文字としてドットを任意に選択することは、予想外に人々を混乱させる方法を除いて、完全に予測不可能です。「.sh」や「.pl」などの正当な語尾は何十年もの間広く使用されてきました。ただし、多くの人はドットの代わりに「_bak」、「_ temp」、または「-bak」を使用します。これはひどいデザインの選択です。それはせいぜい設計上のバグです。
ティーキン

68

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

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

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

    sh -c "mycommand"
    
  • コマンドをbashサブシェルでラップして、bashで実行されることを確認します。

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

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

    #!/bin/bash
    

bashの提案は非常に役立ち、私のcronの問題を修正しました。
マキシムガルシュカ

これにより、1時間のいじり/トラブルシューティングが発生しました。問題に気づいていない場合はさらに困惑します。典型的なシェルである場合にはスクリプトは手動でうまく動作しますがbashcron。ありがとう!
ヘンディ

昔、私は関連する何かsourceに出くわしました。コマンドはbashですが、shではありません。cron / shでは、ピリオド. envfileではなくピリオドを使用しますsource envfile
kungphu

@Clockwork sh "mycommand"sh、mycommandをスクリプトファイルとして実行するように指示します。という意味sh -c "mycommand"ですか?とにかく、この答えはコマンドをbashで実行することに関するものであるように思えますが、なぜshここにコマンドを追加したのですか?
オロリン

@Olorin私の理解では、最初のポイントの目的は、shで試して実行することであり、cronがbashではなくshで実行しているという事実から本当に問題が生じたかどうかを確認することでした。もう一度、私は問題についてほとんど知識がないので、私は間違っているかもしれません。
時計仕掛け

40

タイムゾーンに問題がありました。Cronは新規インストールのタイムゾーンで実行されていました。解決策はcronを再起動することでした:

sudo service cron restart

6
はい、システムのタイムゾーンを変更した後、現在の時刻を考慮しているすべてのサービスを再起動するか、再起動する必要があります。私はすべてをキャッチしたことを確認するために、再起動を好む。
-pbr

ああ、神のために、これで何時間も殺された。* * * * * touch /tmp/cronworks何もしなかった後にサービスの再起動を試みましたが、まだRELOADcronlogにあります。
НЛО

36

スクリプトには絶対パスを使用する必要があります。

たとえば、/bin/grep代わりに使用する必要がありgrepます:

# m h  dom mon dow   command
0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

の代わりに:

# m h  dom mon dow   command
0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

これは、シェルから実行したときに同じコマンドが機能するため、特に注意が必要です。その理由は、ユーザーcronと同じPATH環境変数がないためです。


3
geirha答えを参照してください、あなたはcronののパスを定義する(しなければならない)ことができます
CAPI Etheriel

9
Bzzt。PATHを定義する必要はありません-ここでは絶対パスを使用するのがベストプラクティスです。切り札「私はそれがまさにこのプログラム、私の元のプログラムの前にパスを入れていないいくつかの他の1人の誰か実行したくない」「実行可能ファイルは、いくつかの他のコンピュータ上の別の場所かもしれないので、」
PBR

1
うん、これは私にとってはそうだった、cronの外側でコマンドを直接実行でき、cronの内側で/usr/bin/whateverフルパスが必要だった
-Anentropic

32

crontabコマンドに%シンボルが含まれている場合、cronはそれを解釈しようとします。そのため、その中にを含むコマンド%(dateコマンドの形式指定など)を使用していた場合は、エスケープする必要があります。

それと他の良い落とし穴:http :
//www.pantz.org/software/cron/croninfo.html


これが先週、Cronの仕事を失敗させてきた原因です。最後に、私の日付にはエスケープ文字が含まれていないことがわかりました(エスケープ文字とは何かを探している他の人たちのバックスラッシュ)。わーい!
バリアン


25

Cronは実行可能でないスクリプトを呼び出しています。

chmod +x /path/to/scripスクリプトを実行すると実行可能になり、この問題を解決するはずです。


5
これはに固有のものではなく、コマンドラインからcron実行するだけで簡単に追跡でき/path/to/scriptます。
アダムマタン

4
あなたがスクリプトを実行するために使用している場合. scriptnamesh scriptname、またはbash scriptname、これはなっcron固有の問題。
エリアケイガン

24

ユーザーのパスワードの有効期限が切れている可能性もあります。ルートのパスワードでも期限切れになる場合があります。tail -f /var/log/cron.logパスワードの有効期限が切れてcronが失敗することがあります。これを行うことにより、有効期限が切れないようにパスワードを設定できます。passwd -x -1 <username>

一部のシステム(Debian、Ubuntu)では、cronのログはデフォルトで有効になっていません。である/etc/rsyslog.confまたは/etc/rsyslog.d/50-default.confライン:

# cron.*                          /var/log/cron.log

sudo nano /etc/rsyslog.confコメントを外して編集()する必要があります:

cron.*                          /var/log/cron.log

その後、rsyslogを再起動する必要があります

/etc/init.d/rsyslog restart

または

service rsyslog restart 

ソース:Debian Linuxでcrontabロギングを有効化

一部のシステム(Ubuntu)では、cronの個別のログファイルはデフォルトで有効になっていませんが、cron関連のログがsyslogファイルに表示されます。使用してもよい

cat /var/log/syslog | grep cron -i

cron関連のメッセージを表示します。


Debian(wheezy)を持っていますが、/ etc / init.d / rsyslogはなく、inetutils-syslogdとsysklogdのみがあります。何かをインストールする必要がありますか、それとも2つのうちの1つを再起動するだけですか?
hgoebl

18

cronjobがGUI-appsを呼び出す場合、使用するDISPLAYをそれらに伝える必要があります。

例:cronを使用したFirefoxの起動。

スクリプトにはexport DISPLAY=:0どこかに含まれるべきです。


aplayは何らかの理由でこれを必要としていました。ありがとう
IljaBek

* * * * * export DISPLAY=:0 && <command>
LoMaPh

15

権限の問題は非常に一般的です、私は恐れています。

一般的な回避策は、ルートのcrontabを使用してすべてを実行することであることに注意してください。適切な許可を設定することは、間違いなく見落とされがちな問題です。


まだ存在しないファイルに出力をパイプするように設定されたcrontab行があり、そのファイルのディレクトリがcronユーザーがアクセスできないディレクトリである場合、その行は実行されないことに注意してください。
エヴァンドノヴァン

14

安全でないcronテーブル権限

許可がセキュアでない場合、cronテーブルは拒否されます

sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)

問題はで解決されます

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs

最初に自分でそれを理解し、それからあなたの答えを見つけました!まだどうもありがとう!私の場合、SVNを介して/ var / spool / cron / crontabsにあるいくつかのcrontabを元に戻したり復元したりして、権限を変更しました!
アルフォンス

12

スクリプトは場所に依存します。これは、スクリプトで常に絶対パスを使用することに関連していますが、まったく同じではありません。cronジョブはcd、実行する前に特定のディレクトリに移動する必要がある場合があります。たとえば、適切なデータベース構成などはもちろん、Rakeが正しいタスクを見つけるには、Railsアプリケーションのrakeタスクがアプリケーションルートにある必要があります。

だからのcrontabエントリ

23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

として良いでしょう

23 3 * * * cd / var / www / production / current && / usr / bin / rake db:session_purge RAILS_ENV = production

または、crontabエントリをよりシンプルで脆弱な状態に保つには:

23 3 * * * /home/<user>/scripts/session-purge.sh

次のコードで/home/<user>/scripts/session-purge.sh

cd / var / www / production / current
/ usr / bin / rake db:session_purge RAILS_ENV = production

1
cronから呼び出されるスクリプトがPHPのようなインタプリタ言語で記述されている場合、スクリプト自体に作業ディレクトリを設定する必要があります。たとえば、PHPの場合: chdir(dirname(__FILE__));
Evan Donovan

これに巻き込まれました。スクリプトは以前はホームディレクトリのルートにありましたが、それを移動(およびcrontabを更新)したため、なぜ機能しないのかわかりませんでした。スクリプトは相対パスを使用していましたが、それはスクリプトの場所に相対的であると想定していますが、実際にはそれはcronが使用していた作業ディレクトリであったため、私のホームディレクトリのルートに相対的でしたホームディレクトリのルートにあるときに機能しました(スクリプトの予想される作業ディレクトリと実際の動作偶然一致しためです)。
マイケルジョンソン

11

過去に機能していた Crontabの仕様は、あるcrontabファイルから別のcrontabファイルに移動すると壊れる可能性があります。場合によっては、システムcrontabファイルからユーザーcrontabファイルに、またはその逆に仕様を移動したことが原因です。

cronジョブの指定形式は、ユーザーのcrontabファイル(/ var / spool / cron / usernameまたは/ var / spool / cron / crontabs / username)とシステムcrontab(/etc/crontabおよびのファイル/etc/cron.d)で異なります。

システムのcrontabには、実行するコマンドの直前に追加のフィールド「user」があります。

これによりgeorge; command not found、コマンドをユーザーのcrontabファイルに移動し/etc/crontabたり、ファイルを/etc/cron.dユーザーのcrontabファイルに移動したりするときなどのエラーが発生します。

逆に、cronは/usr/bin/restartxyz is not a valid username、逆の場合に似たようなエラーを送信します。


10

cronスクリプトが--verboseオプションを使用してコマンドを呼び出しています

スクリプトの入力中に自動操縦モードになっていて、-verboseオプションが含まれていたため、cronスクリプトが失敗しました。

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

スクリプトはシェルから実行すると正常に実行されましたが、crontabから実行すると失敗します。これは、シェルから実行すると冗長出力がstdoutに出力されますが、crontabから実行するとどこにも出力されないためです。「v」を削除する簡単な修正:

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands

5
なぜこれが失敗の原因ですか?バッファの問題?
アダムマタン

あなたのmailbox.Soに送信されたcronジョブ経由trriggred任意の出力またはエラーにgooingされるが、我々はこれらのエラーを気にすることを忘れてはならない/ output.Weは、任意のファイルまたは/ dev / nullにそれらをリダイレクトすることができます
Nischay

10

cronが誤って記述されたスケジュールで失敗するのを見た最も頻繁な理由。またはの15 23 * * *代わりに、 午後11時15分にスケジュールされたジョブを指定することは練習が必要です。真夜中の後にジョブの曜日もMFが混乱し、真夜中の後ではありません。特定の日付は、3月3日ではなくほとんど使用されないため、通常は問題になります。不明な場合は、https: //crontab.guru/でオンラインでcronスケジュールを確認してください* * 11 15 *11 15 * * *2-61-5* * 3 1 *

2/3時間指定など、サポートされていないオプションを使用して異なるプラットフォームで作業すると、エラーが発生する可能性があります。これは非常に便利なオプションですが、広く利用できるわけではありません。1-5またはのようなリストに関する問題にも出くわしました1,3,5

修飾されていないパスの使用も問題を引き起こしました。通常/bin:/usr/bin、デフォルトのパスが使用されるため、標準コマンドのみが実行されます。これらのディレクトリには通常、目的のコマンドがありません。これは、非標準コマンドを使用するスクリプトにも影響します。他の環境変数も欠落している可能性があります。

既存のcrontabを完全に上書きすると、問題が発生しました。ファイルコピーから読み込みます。これは、crontab -l破壊された場合に既存のcrontabから回復できます。crontabのコピーを〜/ binに保存します。全体にわたってコメントされ、行で終了し# EOFます。これは、次のようなcrontabエントリから毎日再読み込みされます。

#!/ usr / bin / crontab
#このcrontabをリロードする
#
54 12 * * * $ {HOME} / bin / crontab

上記のreloadコマンドは、crontabを実行するbangパスを持つ実行可能なcrontabに依存しています。一部のシステムでは、コマンドでcrontabを実行し、ファイルを指定する必要があります。ディレクトリがネットワーク共有さcrontab.$(hostname)れている場合、ファイルの名前としてよく使用します。これにより、間違ったcrontabが間違ったサーバーにロードされるケースが最終的に修正されます。

ファイルを使用すると、crontabの内容のバックアップが提供され、一時的な編集(使用する場合のみcrontab -e)を自動的にバックアウトできます。スケジューリングパラメータを正しく取得するのに役立つヘッダーが利用できます。未経験のユーザーがcrontabを編集するときに追加しました。

まれに、ユーザー入力を必要とするコマンドに遭遇しました。これらはcrontabで失敗しますが、一部は入力リダイレクトで機能します。


3
これは、3つの別個の問題をカバーしています。それらを別々の回答に分割できますか?
エリアケイガン

9
30 23 * * * 11:15 PMに翻訳する方法を説明できますか?
JYelton

@JYeltonそれは明らかに間違っていたはずです15 23 * * *。今修正しました。
メレビウス

7

SSHキー経由でアカウントにアクセスしている場合、アカウントにログインすることはできますが、アカウントのパスワードがロックされていることに気付かない場合があります(期限切れまたは無効なパスワードの試行などにより)

システムがPAMを使用していて、アカウントがロックされている場合、これにより、cronジョブの実行を停止できます。(Solarisでこれをテストしましたが、Ubuntuではテストしていません)

/ var / adm / messagesに次のようなメッセージがあります。

10月24日07:51:00 mybox cron [29024]:[ID 731128 auth.notice] pam_unix_account:cronはロックされたアカウントmyuserをローカルホストから検証しようとしています
10月24日07:52:00 mybox cron [29063]:[ID 731128 auth.notice] pam_unix_account:cronがロックされたアカウントmyuserをローカルホストから検証しようとしています
10月24日07:53:00 mybox cron [29098]:[ID 731128 auth.notice] pam_unix_account:ロックされたアカウントmyuserをローカルホストから検証しようとするcron
10月24日07:54:00 mybox cron [29527]:[ID 731128 auth.notice] pam_unix_account:cronはロックされたアカウントmyuserをローカルホストから検証しようとしています

あなたがする必要があるのは、実行するだけです:

#passwd -u <ユーザー名>

rootとしてアカウントのロックを解除すると、crontabが再び機能するはずです。


7

このようなコマンドがある場合:

* * * * * /path/to/script >> /tmp/output

動作せず、出力も表示されません。必ずしもcronが動作していないことを意味するわけではありません。スクリプトが破損し、出力が/ tmp / outputに渡されないstderrに送られる可能性があります。次の出力もキャプチャして、これが当てはまらないことを確認します。

* * * * * /path/to/script >> /tmp/output 2>&1

これが問題の発見に役立つかどうかを確認します。


3

=== Dockerアラート===

ドッカーを使用している場合、

cronをバックグラウンドで実行することができなかったことを追加するのが適切だと思います。

コンテナー内でcronジョブを実行するために、supervisorとranをcron -f他のプロセスと一緒に使用しました。

編集:別の問題-HOSTネットワーキングでコンテナを実行しているときに、それを機能させることもできませんでした。こちらの問題もご覧くださいhttps : //github.com/phusion/baseimage-docker/issues/144



3

データベースから古いトランザクションデータを削除する別のスクリプトを作成するインストールシェルスクリプトを書いていました。タスクの一部としてcron、データベースの負荷が低い任意の時間に実行されるように毎日のジョブを構成する必要がありました。

mycronjobcronスケジュール、ユーザー名、およびコマンドを使用してファイルを作成し、/etc/cron.dディレクトリにコピーしました。私の2つの落とし穴:

  1. mycronjob ファイルを実行するにはルートが所有していなければなりませんでした
  2. ファイルのアクセス許可を644に設定する必要がありました-664は実行されませんでした。

許可の問題は、次の/var/log/syslogようなものとして表示されます。

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)

最初の行は/etc/crontabfileを指し、後の行は私が下に置いたファイルを指します/etc/cront.d


2

crontabが理解できない方法で書かれた行。正しく記述する必要があります。CrontabHowToは次とおりです。


1
これはどのようにデバッグできますか?
アダムマタン

cronのエラーログを確認するのが最も一般的な方法です。IIRC 'crontab -e'は、ファイルを編集した後も構文解析を行いますが、これは普遍的ではない場合があります。
-pbr

2

Cronデーモンは実行されている可能性がありますが、実際には機能していません。cronを再起動してみてください:

sudo /etc/init.d/cron restart

3
本番環境でこのケースを見たことはありません。それが起こらなかったという意味ではありません-UNIXとLinuxを使ってきた30年間で見たことがないというだけです。Cronは非常に堅牢です。
-pbr

1
確かではありませんが、これは実際に私に起こったと思います。pidofcron を試したが何も得られなかった。serviceユーティリティを使用してみましたが、cronが既に実行されていると言いました。このコマンドを実行してからpidof再度実行すると、結果が得られます。
コリーン

2

「crontab -e」経由で行にユーザー名引数を指定してcronに書き込みます。ユーザー(またはシステム管理者)がシェルスクリプトを作成し、自動化しない理由を理解していない例を見てきました。「user」引数は/ etc / crontabに存在しますが、ユーザー定義ファイルには存在しません。そのため、たとえば、個人ファイルは次のようになります。

# m h dom mon dow command

* * */2  *   *  /some/shell/script

一方、/ etc / crontabは次のようになります。

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

では、なぜ後者を行うのでしょうか?許可の設定方法によっては、これが非常に複雑になる場合があります。複雑さを理解していないユーザーや、面倒な作業に煩わされたくないユーザー向けのタスクを自動化するスクリプトを作成しました。アクセス許可を--x------に設定することにより、スクリプトを読み取り可能に(そしておそらく誤って変更することなく)スクリプトを実行可能にできます。ただし、このコマンドを1つのファイルから他のいくつかのファイルと一緒に実行することで(保守が容易になります)、ファイル出力に正しい所有者が割り当てられていることを確認できます。(少なくともUbuntu 10.10で)そうすることで、ファイルの読み取りと実行の両方が不可能になり、さらに/ etc / crontabにピリオドを入れるという前述の問題が発生します(おかしなことに、エラーが発生することはありませんcrontab -e) 。

例として、sudo crontab -eルートパーミッションでスクリプトを実行するために使用されるのインスタンスを見てきましたが、対応chown username file_outputするシェルスクリプトがあります。ずさんですが、動作します。私見、より優雅なオプションは、/etc/crontab宣言されたユーザー名と適切な権限でそれを置くことですので、適切なfile_output場所と所有者になります。


「(少なくともUbuntu 10.10で)そうすることで、ファイルの読み取りと実行の両方が不可能になります。」 明確にする必要があります。/ etc / crontab(デフォルト)には読み取り権限と実行権限が必要です。 「sudo crontab -e」を実行して、「w」権限の必要性と「.sh」などの拡張子の問題の両方を無効にするcronjobを作成します。cronコードを分解して、これがなぜ機能するかを確認する時間はありませんでしたが、詳細に気付きました。
マンジュ

2

Aaron Peartが冗長モードについて言及したことを基に、組み込みモードのデフォルトの動作がprocの開始後に画面に1行以上を出力することである場合、冗長モードではないスクリプトが初期化されても終了しない場合があります。たとえば、リモートサーバーにファイルをダウンロードまたはアップロードするユーティリティであるcurlを使用したイントラネット用のバックアップスクリプトを作成しました。HTTP経由でのみリモートファイルにアクセスできる場合は非常に便利です。'curl http://something.com/somefile.xls ' を使用すると、記述したスクリプトがハングし、完了しなかったため、改行に続いて進行状況行が表示されるため、完了しませんでした。サイレントフラグ(-s)を使用して情報を出力しないように指示し、ファイルのダウンロードに失敗した場合に処理する独自のコードを記述する必要がありました。


1
サイレントモードを持たないプログラムの場合、出力をにリダイレクトできます/dev/null。たとえば、some-command > /dev/nullこれは標準出力のみをリダイレクトし、エラー出力はリダイレクトしません(エラーを通知するため、通常はこれが必要です)。エラー出力もリダイレクトするには、を使用しますsome-command &> /dev/null
エリアケイガン

ええ、それは前述のスクリプトを書くときの私の最初の考えでした。私はそれを使用しなかった理由を忘れてしまいました。おそらく、この解決策を回避したいくつかの非標準的な動作です。冗長/インタラクティブモードが一部のコマンドのデフォルトであることがわかっています(私はあなたを見ています、scp!)。これは、シェルスクリプトをスムーズに操作するために出力を調整する必要があることを意味します。
マンジュ

2

crontableで環境変数を定義できますが、シェルスクリプトではありません。したがって、次のような構造は機能しません。

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

これは、変数がcrontableで解釈されないためです。すべての値が散らかって取得されます。括弧を省略した場合も同じです。したがって、コマンドは実行されず、ログファイルは書き込まれません...

代わりに、すべての環境変数を直接定義する必要があります。

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

2

cron内でタスクが実行されると、stdinは閉じられます。stdinが使用可能かどうかに基づいて異なる動作をするプログラムは、シェルセッションとcronで動作が異なります。

例は、goaccessWebサーバーのログファイルを分析するためのプログラムです。これはcronでは動作しません:

goaccess -a -f /var/log/nginx/access.log > output.html

そしてgoaccess代わりに、レポートを作成するためのヘルプページを示しています。シェルでは、これは

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

修正方法goaccessは、ファイルからではなくstdinからログを読み取るようにすることです。そのため、解決策はcrontabエントリを次のように変更することです。

cat /var/log/nginx/access.log | goaccess -a > output.html

2

私の場合、cronとcrontabには異なる所有者がいました。

働いていませんでした:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

基本的に、cron-configを実行し、質問に正しく答えなければなりませんでした。「ユーザー」アカウントのWin7ユーザーパスワードを入力する必要があったポイントがあります。私が読んだことから、これは潜在的なセキュリティ問題のように見えますが、私は単一のホームネットワークの唯一の管理者なので、私はそれがOKだと決めました。

これが私を導いたコマンドシーケンスです。

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to cygwin@cygwin.com.
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $

1
十分に文書化されていますが、これはCygwin固有のポイントのように見えます。それは本当にaskubuntuに属しますか?
sxc731

2

RHEL7サーバーでは、ルートcronジョブは実行されますが、ユーザージョブは実行されません。ホームディレクトリがないと、ジョブは実行されません(ただし、/ var / log / cronに適切なエラーが表示されます)。ホームディレクトリを作成すると、問題は解決しました。


2

Windowsエディター(sambaなどを使用)を使用してcrontabファイルを編集し、改行を\ n \ rまたは単に\ rに置き換えた場合、cronは実行されません。

また、/ etc / cron.d / *を使用していて、それらのファイルの1つに\ rが含まれている場合、cronはファイルを移動し、不良ファイルにヒットすると停止します。それが問題かどうかわかりませんか?

つかいます:

od -c /etc/cron.d/* | grep \r
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.