多くの場合、crontab
スクリプトはスケジュールどおりに、または期待どおりに実行されません。それには多くの理由があります:
このコミュニティwikiは、crontab
スクリプトが期待どおりに実行されない主な理由を集約することを目的としています。各理由を個別の回答に記入してください。
回答ごとに1つの理由(実行されなかった理由の詳細)を含め、その1つの理由を修正してください。
Cron固有の問題のみを記述してください。シェルからは期待どおりに実行されるが、cronによって誤って実行されるコマンド。
異なる環境
Cronは、環境変数の最小限のセットをジョブに渡します。違いを確認するには、次のようなダミージョブを追加します。
* * * * * env> /tmp/env.output
/tmp/env.output
が作成されるのを待ってから、ジョブを再度削除します。ここで、/tmp/env.output
の内容をenv
の出力と比較し、通常のターミナルで実行します。
ここでよくある「落とし穴」は、PATH
環境変数が異なることです。おそらく、cronスクリプトは、/opt/someApp/bin
のsomecommand
コマンドを使用します。これは、/etc/environment
のPATH
に追加しましたか? cronはそのファイルのPATH
を無視するため、スクリプトからsomecommand
を実行すると、cronで実行すると失敗しますが、端末で実行すると機能します。 /etc/environment
の変数がcronジョブに渡されるのは注目に値しますが、PATH
のようにcronが明示的に設定する変数だけではありません。
これを回避するには、スクリプトの上部で独自の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
私の一番の落とし穴: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)
Cronデーモンが実行されていません。数ヶ月前、私は本当にこれで失敗しました。
タイプ:
pgrep cron
番号が表示されない場合、cronは実行されていません。 Sudo /etc/init.d/cron start
を使用して、cronを開始できます。
編集:/etc/init.dを介してinitスクリプトを呼び出すのではなく、サービスユーティリティを使用します。例
Sudo service cron start
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_-]+$).
したがって、backup.sh
ディレクトリにanalyze-logs.pl
、cron.daily/
というcronスクリプトがある場合は、拡張機能名を削除することをお勧めします。
多くの環境では、cronはsh
を使用してコマンドを実行しますが、多くの人はbash
を使用すると想定しています。
失敗したコマンドに対してこれをテストまたは修正するための提案:
sh
でコマンドを実行して、機能するかどうかを確認してください。
sh -c "mycommand"
コマンドをbashサブシェルでラップして、bashで実行されることを確認します。
bash -c "mybashcommand"
Crontabの上部にあるシェルを設定して、bashですべてのコマンドを実行するようにcronに指示します。
Shell=/bin/bash
コマンドがスクリプトの場合、スクリプトにシバンが含まれていることを確認してください。
#!/bin/bash
タイムゾーンに問題がありました。 Cronは新規インストールのタイムゾーンで実行されていました。解決策はcronを再起動することでした:
Sudo service cron restart
スクリプトには絶対パスを使用する必要があります。
たとえば、grep
の代わりに/bin/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
環境変数がないためです。
Crontabコマンドに%
記号が含まれている場合、cronはそれを解釈しようとします。そのため、%
を含むコマンド(dateコマンドの形式指定など)を使用していた場合、エスケープする必要があります。
それと他の良い落とし穴:
http://www.pantz.org/software/cron/croninfo.html
Cronは実行可能でないスクリプトを呼び出しています。
chmod +x /path/to/scrip
を実行すると、スクリプトが実行可能になり、この問題を解決するはずです。
ユーザーのパスワードの有効期限が切れている可能性もあります。ルートのパスワードでも期限切れになる場合があります。 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関連のメッセージを表示します。
CronjobがGUIアプリを呼び出す場合、使用するDISPLAYを伝える必要があります。
例:cronを使用したFirefoxの起動。
スクリプトにはexport DISPLAY=:0
が含まれている必要があります。
権限の問題は非常に一般的です、私は恐れています。
一般的な回避策は、ルートのcrontabを使用してすべてを実行することであることに注意してください。適切な許可を設定することは、間違いなく見落とされがちな問題です。
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
スクリプトは場所に依存します。これは、スクリプトで常に絶対パスを使用することに関連していますが、まったく同じではありません。 cronジョブは、実行前に特定のディレクトリにcd
する必要がある場合があります。適切なデータベース構成などは言うまでもなく、Railsアプリケーションのrakeタスクは、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
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
または/etc/crontab
のファイルからユーザーのcrontabファイルに移動すると、/etc/cron.d
などのエラーが発生します。
逆に、cronは、逆の場合に/usr/bin/restartxyz is not a valid username
などのエラーを送信します。
Cronが誤って記述されたスケジュールで失敗するのを見た最も頻繁な理由。午後11時15分にスケジュールされたジョブを15 23 * * *
または* * 11 15 *
の代わりに11 15 * * *
として指定することは練習が必要です。真夜中以降のジョブの曜日も混乱しますM-Fは2-6
ではなく、真夜中以降の1-5
です。特定の日付はほとんど使用されないため、通常は問題になります* * 3 1 *
は3月3日ではありません。不明な場合は、 https://crontab.guru/ でオンラインでcronスケジュールを確認してください。
時間指定で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で失敗しますが、一部は入力リダイレクトで機能します。
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
SSHキー経由でアカウントにアクセスしている場合、アカウントにログインすることはできますが、アカウントのパスワードがロックされていることに気付かない場合があります(たとえば、期限切れまたは無効なパスワード試行のため)
システムがPAMを使用していて、アカウントがロックされている場合、これにより、cronジョブの実行を停止できます。 (Solarisでこれをテストしましたが、Ubuntuではテストしていません)
/ var/adm/messagesに次のようなメッセージがあります。
10月24日07:51:00 mybox cron [29024]:[ID 731128 auth.notice] pam_unix_account:ロックされたアカウントmyuserをローカルホストから検証しようとしています Oct 24 07:52:00 mybox cron [29063]:[ID 731128 auth.notice] pam_unix_account:cronがローカルホストからロックされたアカウントmyuserを検証しようとしています Oct 24 07:53:00 mybox cron [29098]:[ID 731128 auth.notice] pam_unix_account :ローカルホストからロックされたアカウントmyuserを検証しようとするcron Oct 24 07:54:00 mybox cron [29527]:[ID 731128 auth.notice] pam_unix_account:ロックされたアカウントmyuserをローカルホストから検証しようとしています。 ____。]
あなたがする必要があるのは、実行するだけです:
#passwd -u <ユーザー名>
rootとしてアカウントのロックを解除すると、crontabが再び機能するはずです。
このようなコマンドがある場合:
* * * * * /path/to/script >> /tmp/output
動作せず、出力も表示されません。必ずしもcronが動作していないことを意味するわけではありません。スクリプトが破損し、出力がstderrになり、/ tmp/outputに渡されません。次の出力もキャプチャして、これが当てはまらないことを確認します。
* * * * * /path/to/script >> /tmp/output 2>&1
これが問題の発見に役立つかどうかを確認します。
データベースから古いトランザクションデータを削除する別のスクリプトを作成するインストールシェルスクリプトを書いていました。タスクの一部として、データベースの負荷が低い任意の時間に実行されるように毎日cron
ジョブを構成する必要がありました。
Cronスケジュール、ユーザー名、コマンドを使用してファイルmycronjob
を作成し、/etc/cron.d
ディレクトリにコピーしました。私の2つの落とし穴:
mycronjob
ファイルを実行するには、rootが所有している必要がありましたパーミッションの問題は、/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/crontab
ファイルを参照し、後の行は/etc/cront.d
の下に配置したファイルを参照します。
=== Dockerアラート===
ドッカーを使用している場合、
Cronをバックグラウンドで実行することができなかったことを追加するのが適切だと思います。
コンテナー内でcronジョブを実行するために、supervisorを使用し、cron -f
を他のプロセスと一緒に実行しました。
編集:別の問題-ホストネットワーキングでコンテナを実行しているときに、それを機能させることもできませんでした。こちらの問題もご覧ください: https://github.com/phusion/baseimage-docker/issues/144
Cronデーモンは実行されている可能性がありますが、実際には機能していません。 cronを再起動してみてください:
Sudo /etc/init.d/cron restart
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}
Aaron Peartが冗長モードについて述べたことを基に、組み込みモードのデフォルトの動作がprocの開始後に1行以上を画面に出力する場合、冗長モードではないスクリプトが初期化されても終了しない場合があります。たとえば、ファイルをリモートサーバーにダウンロードまたはアップロードするユーティリティであるcurlを使用したイントラネット用のバックアップスクリプトを作成しました。HTTP経由でのみリモートファイルにアクセスできる場合は非常に便利です。 'curl http://something.com/somefile.xls 'を使用すると、記述したスクリプトがハングし、完了せずに、改行に続いて進行状況行が表示されるため、完了しませんでした。情報を出力しないようにサイレントフラグ(-s)を使用し、ファイルのダウンロードに失敗した場合に処理する独自のコードを記述する必要がありました。
16.04で、syslogにこのエラーがある場合
(CRON) error (can't fork)
試してください:
systemctl status cron.service
結果:
Tasks: num_task (limit: 512)
num_task
が制限に近い場合:
systemctl set-property cron.service TasksMax=new_max
new_max
を適切な値に置き換えます。
Crontabが理解できない方法で書かれた行。正しく記述する必要があります。 CrontabHowTo です。
RHEL7サーバーでは、ルートcronジョブは実行されますが、ユーザージョブは実行されません。ホームディレクトリがないと、ジョブは実行されません(ただし、/ var/log/cronに適切なエラーが表示されます)。ホームディレクトリを作成すると、問題は解決しました。
「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
は適切な場所と所有者になります。
Cron内でタスクが実行されると、stdinは閉じられます。 stdinが使用可能かどうかに基づいて異なる動作をするプログラムは、シェルセッションとcronで動作が異なります。
例は、Webサーバーのログファイルを分析するためのプログラムgoaccess
です。これは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
私の場合、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 [email protected].
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 ~ $
Windowsエディター(sambaなどを使用)を使用してcrontabファイルを編集し、改行を\ n\rまたは単に\ rに置き換えた場合、cronは実行されません。
また、/ etc/cron.d/*を使用していて、それらのファイルの1つに\ rが含まれている場合、cronはファイルを移動し、不良ファイルにヒットすると停止します。それが問題かどうかわかりませんか?
つかいます:
od -c /etc/cron.d/* | grep \r
UBuntu 16.04(および他の多くのバージョン)のデフォルトの.bashrcファイルには、何もしないメカニズムが組み込まれています インタラクティブなシェルでない場合
これにより、cronによって実行されるスクリプト内でファイルが正しく取得されるのを防ぐことができます。これを防ぐには、.bashrcファイルの先頭から次の行をコメントアウトします。
Ubuntu 16.04
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Ubuntu 12.04およびその他のバージョン
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Cronが.bashrcファイルのソースとなるスクリプトを実行する場合にこれらが残されている限り、実際に端末内で使用されている環境変数を取得することはありません!
別の落とし穴:
crontab -e
と入力してエディター内に保存しても、効果はありません。変更に応じて追加または更新するには、エディターを終了する必要があります(たとえば、Vimで:x
を使用します)。
(crontab -e
は「cronファイルの編集、cronファイルからの更新」を効果的に実行するため、エディターを閉じるまでエディターでブロックされます。)
正規表現でgrepを呼び出すスクリプトに問題がありました。スクリプトがcrontabから呼び出されたときに機能する正規表現もあれば、そうでないものもありました。 [[:print:]]は機能しませんでした。環境変数LANGは、[a-z]や[[:print:]]などの文字セットに影響を与えます。 LANG環境変数をcrontabの最上部、つまり「LANG = en_GB.UTF-8」に貼り付けたとき、スクリプトがcrontabから呼び出されたときにgrepの正規表現はすべて正常に機能しました。 HTH。
ロギング許可
/var/log/
はluser
アカウントによって書き込みできないため、非常に単純なcrontabは実行されません!
* * * * * /usr/local/bin/teamviewer_check >> /var/log/teamviewer.log 2>&1
解決策:ファイルをルートとして作成し、chmod
から777
へ
/etc/rsyslog.d/50-default.conf
でcronロギングを有効にするという以前の提案のおかげで、syslogエントリ(No MTA installed, discarding output)
に至り、次に "(CRON)情報(MTAがインストールされていない、出力を破棄する) syslog ローカルモードでのpostfixのインストール、tail/var/mail/luser、/bin/sh: 1: cannot create /var/log/teamviewer.log: Permission denied
別の警告:
cronスクリプトをユーザーのホームディレクトリに置かないでください。
私はちょうどすべてが良いように見えるという問題を抱えていましたが、しばらくすると-おそらくログアウトしてから数時間後、cronジョブが機能しなくなり、これらのメッセージがログに表示されます:
Signature not found in user keyring
Perhaps try the interactive 'ecryptfs-mount-private'
少なくとも私の知る限り、ホームディレクトリは暗号化されていません。それでも、これらのスクリプトをホームディレクトリの外に移動すると、問題は解決しました。
私のcrontabは、ユーザーとしてログインしたときにのみ機能しました。
私は見つけました nixおよびLinux SEでここに提案された解決策
問題は、スクリップが暗号化されたホームディレクトリにあったことです。そのため、ログに記録されたときにマウント解除され、使用できなくなります。コマンドmount
を使用して、ホームディレクトリが暗号化のためにマウントされているかどうかを確認できます。
スクリプトを/usr/local/bin
フォルダーに入れることで問題を修正しました。
何時間も問題を見つけた後、私はWindows
(notepad ++)からシェルスクリプトを編集していました。 Linux
サーバーと、改行文字を忘れました。
ファイルを編集するのにNotepad ++を使用していたので、 EOL Conversion toUnix改行文字を取得するために、完全に機能しました。
それが役に立てば幸い!
crontabがrun-parts /etc/cron.dailyのように言及している場合、run-partsはスクリプトの実行を拒否している可能性があります。私の場合、cron.dailyのスクリプトは#!/ bin/shで始まっていません。
スクリプトを単独でディレクトリに配置し、そのディレクトリに対してrun-partsを実行することでこれを発見しました。
最近、これが起こりました。次のように、PATH
を変更した2行がありました。
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/ernesto/bin
その後、ファイルの後半で:
PATH=$PATH:/some/other/path
通常、シェルで解釈されるコンテキストで行われます。ただし、$ PATHは展開されていないようで、すべてのジョブが失敗します。解決策は、すべてを1行に配置することです。
編集:
次の通常のanacronの繰り返しでジョブが正常に機能することを確認するまで待てないので、実行しました。
anacron -fnd "jobname"
「jobname」は、anacrontabで指定されたジョブ識別子です。これにより、同じanacronプロセスによって、順番に遅延なくジョブが実行されます。
ユーザーのパスワードの有効期限が切れると、cronジョブは実行されません。
これの1つの兆候は、cronログ(通常、Ubuntuの/var/log/syslog
、私は信じる)が「認証トークンはもはや有効ではありません。新しいものが必要です」などのメッセージを含む場合です。
Sudo chage -l the_username
を実行すると、この問題を確認できます。
期限切れのパスワードの例を次に示します。
$ Sudo chage -l root
Last password change : password must be changed
Password expires : password must be changed
Password inactive : password must be changed
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 14600
Number of days of warning before password expires : 14
修正は、パスワードを変更することです。例えば:
Sudo -u root passwd
次に、指示に従って、プロンプトに従って新しいパスワードを指定します。
https://serverfault.com/questions/449651/why-is-my-crontab-not-working-and-how-can-i-troubleshoot-it#comment966708_544905 に感謝しますここで正しい方向。私の場合、そのコメンターに関しては、DigitalOceanボックスのルートユーザーでした。
使いました:
* * * * * DISPLAY=:0 /path/to/your/app
~/.dbus
ディレクトリの所有者はあなたではなく、ルートであるため、失敗しました。確認してください:
ls -l ~/.dbus
私はかつてたくさんの制限を持つ共有サーバーで働いていました。
ここでのすべての答え(PATH、Shell、bash -c、...)は、crontabでスクリプトを機能させることができませんでした。
コマンドをcrontab自体ではなく、PATH、Shell、およびShebangを使用してコマンドを少しスクリプトファイルに入れると、完全に機能しました。許可を700に変更する必要がありました。
Cronは正常に動作している場合もありますが、実行したいスクリプトまたはコマンドがサイレントで失敗し、間違ったツリーを作成することがあります。
そのような場合、ターゲットを別の短いスクリプトでラップし、目に見えるデバッグコード(date
の出力を含む)を出力し、リダイレクトを使用して検査する証拠を取得すると便利です。ターゲットがスクリプトの場合、sh -x
を囲むとさらに役立ちます。
Crontabエントリ(常にcrontab -e
で編集)は次のようになります。
00 14 * * * (sh -x /tmp/my_wrapper_script) >> /tmp/debug.log 2>&1
/tmp/debug.log
とそのタイムスタンプを調べます。空の場合、存在しない場合、またはタイムスタンプが14:00直後にない場合(この例では)cronの問題がある可能性があります。そうでない場合、実際のターゲットアクションをデバッグする必要があり、cronは正常に動作しています
CronでSudo
を使用する際に問題が発生しました。
基本的に、特定のユーザーとしてコマンドを実行したかったので、最初にコマンドラインsu
でテストし、エラーThis account is not available
を返しました。 Sudo
を使用すると、コマンドはエラーなしで実行されました。
ただし、cronから実行すると、Sudo
コマンドは次のエラーを返しました:Sudo: sorry, you must have a tty to run Sudo
。
後でrunuser
を使用して、コマンドを実行するためのシェルを指定すると機能することがわかりました。
/etc/cron.*
ディレクトリ内でスクリプトを実行する場合は、スクリプトを確認してください。
(^[a-zA-Z0-9_-]+$)
と一致します。そのため、たとえば、拡張子(.sh
など)を使用してスクリプトを作成した場合は機能しません。
1時間ごとに実行されるスクリプトの名前を出力するには、次を試してください。
Sudo run-parts --report --test /etc/cron.hourly