web-dev-qa-db-ja.com

ルートcronジョブを適切にセットアップする方法

ルートcronジョブをセットアップして、ルートとしてBashスクリプトを実行し、毎時、毎月、毎月、7分37分に実行しようとしました。このスクリプトは/usr/binにあり、tunlrupdate.shという名前です。 TunlrのDNSを更新します。

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

このBashスクリプトは利用可能です ここ

呼び出されると、スクリプトは/var/log/tunlr.logにあるログに何が起こっているかを書き込みます

このルートcronジョブを追加するには、ルートのcrontabの標準を使用しました

Sudo crontab -e

そして、これらの2行を最後に挿入しました。 cronがrootとしてスクリプトを実行することを期待しています。

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

後のコマンドSudo crontab -lは、cronジョブが挿入されたことを確認しました。

Ubuntuを再起動し、cronジョブが適切に起動されたかどうかをログファイルでチェックしていました。ただし、ログファイルには何もありません/var/log/tunlr.logは、ジョブが正常に起動されなかったことを意味します。

コマンドラインからスクリプトを実行する場合、私はそれをチェックしました

Sudo /usr/bin/tunlrupdate.sh

その後、ログファイルはそれに応じて更新されます。

システムでこのcronジョブが計画どおりに実行されないのはなぜですか?

更新1:これまでに提案されたすべてのソリューションは機能しません。システムログSudo grep CRON /var/log/syslogを一覧表示するCLIについてOlliに感謝します。ただし、CRONエラーが発生しました

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

推奨されるPATH =を挿入し、スクリプト内の関数にルートからの絶対パスを使用するか、ここでこの推奨ソリューションを使用しないでください。まだこのエラーが発生します。

いくつかの検索の後、説明されているようにファイル/usr/lib/php5/maxlifetimeのエラーを特定しました hereChange #!/bin/sh -e --> #!/bin/sh -x

次に、システムのCRONエラーログを一覧表示します

Sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

まだbashスクリプトを実行できません。今回はログにエラーは表示されません。確実にするために、これはスクリプトの内容ではありませんでした。スクリプトを次の3行に減らしました。

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

まだcronジョブを取得できません。ログファイルには何も書き込まれません。空のスクリプトでもcronで実行されない場合がありますか?わかりません。次の2行に縮小したスクリプトを試してみました。

#!/bin/bash
exit 0

それでも同じエラーログ。 cronスクリプトが通過しません...

32
Antonio

さて、ついに実用的なソリューション。 syslogで、反復的で興味深いものを見ました:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

Rootはcmdとして認識されなかったようです。既に$ Sudo /usr/bin/tunlrupdate.shを使用してルートのcronを使用しているため。次に、元のスクリプト(UNIX cmdの日付の間違いを修正:月は%Mで、分は%Mで使用されました)で次の(cron行からルートを削除します)を試しました。

$ Sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

これが最終的なソリューションであることが判明しました。 [私はcron行にrootを付けた誤った行を示す多くの文献を見つけましたが。それは間違いだった]。

9
Antonio

スクリプトを通常のユーザーとして実行する場合:

crontab -e

そして次の行を追加します。

07,37 * * * * /usr/bin/tunlrupdate.sh

スクリプトをrootとして実行する場合:

Sudo crontab -e

そして同じ行を追加します:

07,37 * * * * /usr/bin/tunlrupdate.sh
64
Guillaume

Cronの1つの「問題」は、環境変数の不足です(明らかなセキュリティ上の理由)。おそらくPATHとHOMEがありません。スクリプトで直接定義するか、crontabファイルで定義できます。

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

スクリプトで必要なすべての必要な変数が定義されるまでテストする必要があります。

2
Alexis Wilke

Cronエラーメッセージは、通常-デフォルトで-メールで送信されます。 Sudo mailを使用してルートのメールがあるかどうかを確認するか、/var/mail/rootの内容を確認するだけで確認できます(例:Sudo less /var/mail/root)。


メールメッセージが役に立たない場合は、/var/log/syslogも確認してください。

Sudo grep CRON /var/log/syslog

Alexis Wilkeが既に言ったように、cronには環境変数を設定するための異なるメカニズムがあります。

スクリプトに必要なもの

PATH=/sbin:/bin:/usr/bin

crontabへ。 HOMEは必要ありません。スクリプトでは、dateの代わりに/bin/dateなどの絶対パスを使用する必要があります。 which command_nameを使用して、各コマンドの適切なパスを見つけることができます。

$ which date
/bin/date
0
Olli

この行をスクリプトに追加できます。したがって、cronログを確認し、ジョブが実行されたことを確認したら、crontabの同じ$ PATHを取得できます。

/bin/echo $PATH > /root/path.txt

おそらく、cronスクリプトの問題を診断するためにできる最善の方法は、スクリプトのenvコマンドでSOのすべての環境変数を取得することです。したがって、この行をスクリプトに追加するだけです。次に、出力を分析できますallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

別のトリックは、スクリプトの出力を特定の場所に向けることです。 /root/log.logを追加します。これにより、スクリプトのすべての出力が/root/log.logで維持されます

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

また、テストとチェックを容易にするために、各分を実行するようにスクリプトをスケジュールできます。

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
0
Cassio Seffrin