Maison > Article > Opération et maintenance > Raisons pour lesquelles Linux crond ne s'exécute pas
Afin de surveiller régulièrement l'utilisation du processeur, de la mémoire et de la charge du système Linux, j'ai écrit un script Linux Shell Lorsqu'il atteint une certaine valeur, il enverra régulièrement des notifications par e-mail. Cependant, lorsque j'ai demandé à crond d'exécuter périodiquement le script pour envoyer des notifications par e-mail, j'ai rencontré un problème après avoir ajouté le script d'exécution à crontab -e, j'ai constaté que le script n'était pas exécuté.
Cependant, il est normal d'exécuter manuellement la commande du script Shell (./mimvp-email.sh), car l'exécution manuelle du script peut obtenir les variables d'environnement Linux par défaut, mais elles ne peuvent pas être obtenues via des tâches planifiées. effectué par les variables d'environnement Crontab.
Après avoir analysé les raisons, les principales raisons pour lesquelles crond n'est pas exécuté sont les suivantes :
1. Le service crond n'est pas démarré
ps -ef | grep -v grep | grep crond // 查看crond服务是否运行 service crond start //关闭服务 service crond stop //关闭服务 service crond restart //重启服务 service crond reload //重新载入配置
2. n'exécute pas les autorisations crond
Le fichier vim /etc/cron.deny est utilisé pour contrôler quels utilisateurs ne peuvent pas exécuter les fonctions du service crond.
Vous pouvez vous supprimer du fichier, ou contacter root
3 crontab ne fournit pas les variables d'environnement de l'utilisateur exécutant
Solution : ajoutez ce qui suit au script. Une ligne :
./etc/profile
~/.bash_profile
4. Aucun chemin absolu n'est utilisé
Le chemin absolu inclut ici le chemin dans le script et crond Il y a deux aspects du chemin dans la commande, par exemple :
*/10 * * * * sh /root/script/mysql_files_monitor.sh &
5. ci-dessus ne résout pas le problème, vous pouvez réessayer Trouvez le problème :
1) Vérifiez l'e-mail Au cours de ce processus, l'utilisateur devrait recevoir un e-mail, comme cette invite :
vim. /var/spool/mail/root
Vous avez du courrier dans /var/spool/mail/root
Allez jeter un œil au contenu crond là-bas
Le fichier est trop gros pour être ouvert, vous pouvez intercepter la dernière vue des 1000 lignes
tail -n 1000 /var/spool/mail/root > aaa.txt && vim aaa.txt
2) Ajouter une sortie au script pour le débogage
Vous pouvez ajouter
echo $PATH > /tmp/test.log
dans le script crontab et le comparer avec echo $ PATH
6 lors de l'exécution du script dans le terminal, il y a trop de processus crond, tuez-les tous et redémarrez le service crond
#!/bin/bash
pour i in $ (ps -elf | grep -v grep | grep crond | awk " " ' {print $4}' ); do
kill -9 $i
done
Utilisez root pour effectuer un redémarrez et le problème est résolu :
service crond restart
7. crond empêche une exécution répétée avant que le script ne soit terminé dans le cycle
Expérience personnelle : flock -xn my .lock cmd
my.lock est un fichier, il peut s'agir de n'importe quel fichier et vous pouvez créer un nouveau fichier vide
Lorsque flock obtient le verrou, il exécutera le processus de test cmd
suivant :
$1 : flock -xn my.lock sleep 20
$2 : flock -xn my.lock ls
Seulement lorsque 1 revient, le ls de 2 réussira
Si un script doit s'exécuter pendant 30 minutes, vous pouvez définir l'intervalle du script dans Crontab sur au moins une heure pour éviter les conflits. La pire situation est que le script peut ne pas se terminer pendant le cycle d'exécution, puis le deuxième script recommence à s'exécuter. Comment puis-je m'assurer qu'une seule instance du script est exécutée ? Une méthode utile consiste à utiliser lockf (lockf sous FreeBSD 8.1, flock sous CentOS 5.5) pour vérifier si un verrou de fichier peut être obtenu avant l'exécution du script afin d'éviter les conflits d'exécution du script.
Les paramètres lockf sont les suivants
-k : Attendez d'obtenir le verrouillage du fichier.
-s : silencieux, n'envoie aucune information, même si le verrouillage du fichier ne peut être obtenu.
-t secondes : définissez le délai d'attente sur quelques secondes. S'il dépasse le temps, il abandonnera automatiquement.
Avant d'exécuter la tâche planifiée crontab suivante, vous devez obtenir le fichier temporaire create.lock file lock Le contenu de la tâche planifiée crontab est le suivant :
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)
Si première Si la première instance ne termine pas son exécution dans les 10 minutes, la deuxième instance ne s'exécutera pas. J'avais l'habitude de résoudre ce problème via des scripts Shell, par exemple en utilisant une boucle while...do, puis en l'exécutant en arrière-plan. Mais plus tard, j'ai découvert qu'il était plus simple d'utiliser la méthode flock ou lockf.
Ci-joint l'utilisation de flock sous Linux :
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超标解决办法。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!