Linux システムの CPU、メモリ、負荷の使用状況を定期的に監視するために、一定の値に達したときに定期的に電子メール通知を送信する Linux シェル スクリプトを作成しました。しかし、電子メール通知を送信するスクリプトを定期的に実行するように crond に依頼したところ、実行スクリプトを crontab -e に追加した後、スクリプトが実行されないことがわかりました。
ただし、シェル スクリプト コマンド (./mimvp-email.sh) を手動で実行するのが通常です。スクリプトを手動で実行するとデフォルトで Linux 環境変数を取得できますが、Crontab によって実行されるスケジュールされたタスクを通じて環境変数が取得されないためです。は入手できません。
原因を分析した結果、crondが実行されない主な理由は以下の通りです:
1. crondサービスが開始されていない
ps -ef | grep -v grep | grep crond // 查看crond服务是否运行 service crond start //关闭服务 service crond stop //关闭服务 service crond restart //重启服务 service crond reload //重新载入配置
2. ユーザーにcrond
vim /etc/を実行する権限がありません。 cron.deny ファイルは、どのユーザーが crond サービスの機能を実行できないかを制御するために使用されます。
ファイルから自分自身を削除するか、root に連絡してください
3. Crontab は実行されたユーザーの環境変数を提供しません
解決策: 次の行をスクリプトに追加します: /etc/profile
。 /.bash_profile
4. 絶対パスは使用されません
ここでの絶対パスには、スクリプト内のパスと crond コマンド内のパスの両方が含まれます。例:
*/10 * * * * sh /root/script /mysql_files_monitor .sh &
5. 上記で問題が解決しない場合は、もう一度問題を探してください:
1) このプロセス中に、ユーザーは次のような電子メールを受信するはずです。
vim /var/spool/mail/root
/var/spool/mail/root にメールがあります
中にある crond の内容を見てください
ファイルは大きすぎて開けません、インターセプトできます最後の 1000 行を表示します
tail -n 1000 /var/spool/mail/root > aaa.txt && vim aaa.txt
2) デバッグ用にスクリプトに出力を追加します
エコーを追加できますcrontab スクリプトの $PATH > ; /tmp/test.log
ターミナルでスクリプトを実行するときの echo $PATH と比較します
6. crond プロセスが多すぎるので、すべて強制終了して crond サービスを再起動します
#!/bin/bash
for i in $(ps - elf | grep -v grep | grep crond | awk -F " " '{print $4}' ); dokill -9 $i
done
Use root再起動を実行すると、問題は解決します:
service crond restart
7. crond は、サイクル内でスクリプトが完了する前に繰り返し実行されるのを防ぎます
個人的な経験: flock -xn my.lock cmd
my.lock はファイルは任意のファイルで、空のファイルを作成できますflock がロックを取得すると、次の cmd
テスト プロセスが実行されます:
$1: flock -xn my.lock sleep 20
スクリプトを 30 分間実行する場合、競合を避けるために Crontab でスクリプト間隔を少なくとも 1 時間に設定できます。さらに悪い状況は、スクリプトが実行サイクル中に完了せず、その後 2 番目のスクリプトが再び実行を開始する可能性があることです。スクリプトのインスタンスが 1 つだけ実行されるようにするにはどうすればよいですか?便利な方法は、lockf (FreeBSD 8.1 では lockf、CentOS 5.5 では flock) を使用して、スクリプトの実行前にファイル ロックを取得できるかどうかを確認し、スクリプト実行の競合を防ぐことです。
lockfパラメータは以下の通りです
-k: ファイルロックの取得を待ちます。
-s: サイレント、ファイルロックを取得できない場合でも情報を送信しません。
-t 秒: タイムアウトを秒に設定します。時間を超えると自動的に終了します。
次の crontab スケジュール タスクを実行する前に、一時ファイル create.lock ファイル ロックを取得する必要があります。 crontab スケジュール タスクの内容は次のとおりです:
1 */10 * * * * (lockf -s -t) 0 /tmp/create.lock / usr/bin/python /home/project/cron/create_tab.py >> /home/project/logs/create.log 2>&1)
最初のインスタンスが終了しない場合10 分以内に実行しないと、2 番目のインスタンスは実行されません。以前は、while...do ループを使用してバックグラウンドで実行するなど、シェル スクリプトを通じてこの問題を解決していました。しかし、後で、flock または lockf メソッドを使用する方が簡単であることがわかりました。
Linux での flock の使用法を添付します:
flock (util-linux 2.13-pre7)
Usage: flock [-sxun][-w #] fd#
flock [-sxon][-w #] file [-c] command...
-s --shared Get a shared lock
#共享锁,在定向为某文件的FD上设置共享锁而未释放锁的时间内,其他进程试图在定向为此文件的FD上设置独占锁的请求失败,而其他进程试图在定向为此文件的FD上设置共享锁的请求会成功
-x --exclusive Get an exclusive lock
#独占或排他锁,在定向为某文件的FD上设置独占锁而未释放锁的时间内,其他进程试图在定向为此文件的FD上设置共享锁或独占锁都会失败。只要未设置-s参数,此参数默认被设置
-u --unlock Remove a lock
#手动解锁,一般情况不必须,当FD关闭时,系统会自动解锁,此参数用于脚本命令一部分需要异步执行,一部分可以同步执行的情况
-n --nonblock Fail rather than wait
#为非阻塞模式,当试图设置锁失败,采用非阻塞模式,直接返回1,
-w --timeout Wait for a limited amount of time
#设置阻塞超时,当超过设置的秒数,就跳出阻塞,返回1
-o --close Close file descriptor before running command
-c --command Run a single command string through the shell 执行其后的comand
-h --help Display this text
-V --version Display version
举个例子执行如下脚本:
每天23:30的时候执行一个脚本,但是执行前必须要获得排他文件锁,否则无法执行命令
1 30 23 * * * flock -xn /tmp/test.lock -c '/usr/local/php test.php'
8、; 和 && 区别
“;” 和 “&&”是有区别的
“;”:不管cmd1执行的结果如何,都执行cmd2
“&&”:只有cmd1执行返回的结果是成功的,才执行cmd2
cmd1 && cmd2; cmd3
- cmd1 is executed, if it succeeds, then execute cmd2. and then cmd3 (regardless of cmd2 success or not)
- cmd1 is executed, if it fails, then cmd3 (cmd2 won't be executed)
9、如果遇到shell语法错误
Syntax error: "(" unexpected
解决方法:
需指定shell解释器命令:SHELL=/bin/bash(请参见上面 crontab编辑示例 SHELL=/bin/bash)
或者参见: LINUX - BASH Syntax Error
如果遇到路径错误
在 /var/spool/crontab/yanggang 中,添加了如下命令,在日志文件 /var/spool/mail/yanggang 中提示找不到 xxx.sh 路径
30 * * * * /home/barry/top800/top10/top10_fruits/top10_all.sh
或
30 * * * * bash /home/barry/top800/top10/top10_fruits/top10_all.sh
这是因为你在crontab中使用了绝对路径执行脚本 top10_all.sh,因此在脚本 top10_all.sh 中引用的其它脚本也都需要使用绝对路径,才能被crontab找到并执行。
那么该如何避免绝对路径呢,推荐采用如下格式:
30 * * * * cd /home/barry/top800/top10/top10_fruits/ && ./top10_all.sh(推荐用此方式)
先进入该目录,然后在执行脚本;否则,执行脚本中的其它脚本都需要加绝对路径
参考推荐:
CentOS 7.2上 crontab 计划任务
linux定时运行命令脚本——crontab
CentOS crontab 定时任务不执行的解决
WordPress定时任务(wp-cron.php)造成主机CPU超标解决办法。
以上がLinux crondが実行されない理由の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。