49 votes

Comment configurer correctement une tâche cron racine

J'ai essayé de mettre en place une tâche cron racine pour exécuter un script Bash en tant que root, pour s'exécuter à la minute 7 et 37, toutes les heures, tous les jours du mois, tous les mois. Ce script est situé dans /usr/bin et nommé tunlrupdate.sh. Il met à jour le DNS de Tunlr.

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

Ce script Bash est disponible ici.

Lorsqu'il est invoqué, le script écrit ce qui se passe dans un journal situé dans /var/log/tunlr.log

Pour ajouter cette tâche cron racine, j'ai utilisé la norme pour le crontab de root

sudo crontab -e

Et j'ai inséré ces 2 lignes à la fin. Je m'attends à ce que cron exécute le script en tant que root.

# vérifier les mises à jour DNS de Tunlr toutes les 30 minutes à l'heure + 7 mn et l'heure + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Une commande ultérieure sudo crontab -l a confirmé que la tâche cron a été insérée.

J'ai redémarré Ubuntu et vérifié dans le fichier journal si la tâche cron était lancée correctement. Cependant, il n'y a rien dans le fichier journal /var/log/tunlr.log, ce qui signifie que la tâche n'a jamais été lancée avec succès.

J'ai vérifié que si je lance le script depuis la ligne de commande

sudo /usr/bin/tunlrupdate.sh

alors le fichier journal est mis à jour en conséquence.

Pourquoi cette tâche cron ne s'exécute-t-elle pas comme prévu sur mon système ?

MISE À JOUR 1 : Toutes les solutions proposées jusqu'à présent ne fonctionnent pas. Je remercie Olli pour une CLI pour lister le journal système sudo grep CRON /var/log/syslog. Cependant, j'ai obtenu une erreur 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)

avec l'insertion suggérée de PATH= et l'utilisation d'un chemin absolu de root pour les fonctions dans le script ou sans ces solutions suggérées ici. J'obtiens toujours cette erreur.

Après quelques recherches, j'ai identifié l'erreur dans le fichier /usr/lib/php5/maxlifetime comme expliqué ici : Change #!/bin/sh -e --> #!/bin/sh -x

Ensuite, en listant le journal d'erreurs CRON de mon système

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)

Je ne parviens toujours pas à exécuter le script bash. Cette fois, aucune erreur n'est affichée dans le journal. Pour m'assurer que ce n'était pas le contenu du script, j'ai réduit le script aux 3 lignes suivantes :

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

Je n'arrive toujours pas à obtenir la tâche cron. Rien n'est écrit dans le fichier journal. Donc même un script vide ne s'exécutera peut-être pas dans cron ? Je ne comprends pas. J'essaie maintenant un script réduit à ces 2 lignes :

#!/bin/bash
exit 0

Et toujours le même journal d'erreurs. Le script cron ne passe pas...

94voto

Guillaume Points 1961

Si vous souhaitez exécuter un script en tant qu'utilisateur normal:

crontab -e

Et ajoutez la ligne:

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

Si vous souhaitez exécuter votre script en tant que root:

sudo crontab -e

Et ajoutez la même ligne:

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

11voto

Antonio Points 1391

Eh bien, enfin la solution de travail. Dans le syslog, j'ai vu le message répétitif et intrigant :

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

Cela ressemble à root n'a pas été reconnu comme une commande. Comme j'ai déjà utilisé le cron de root en utilisant $ sudo /usr/bin/tunlrupdate.sh. Ensuite, j'ai essayé avec le script original (corrigé pour une erreur dans la commande UNIX de date : %m qui est le mois a été utilisé pour les minutes qui est %M) le suivant (qui supprime le root de la ligne cron) :

$ sudo crontab -e
# vérifier les mises à jour du DNS Tunlr toutes les 30 minutes à l'heure + 7 mn et à l'heure + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

Cela s'est avéré être la solution finale. [Bien que j'aie trouvé des dizaines de documents décrivant la ligne erronée avec root dans la ligne cron. C'était une erreur].

4voto

Alexis Wilke Points 2410

Un "problème" avec cron est le manque de variables d'environnement (pour des raisons de sécurité évidentes). Vous manquez probablement de PATH et HOME. Vous pouvez les définir dans le script directement ou dans le fichier crontab.

# vérifier les mises à jour de Tunlr DNS toutes les 30 minutes à l'heure + 7 mn et l'heure + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Il faudra tester jusqu'à ce que toutes les variables nécessaires soient définies comme requis par le script.

1voto

Olli Points 8476

Les messages d'erreur de Cron sont généralement - par défaut - envoyés par e-mail. Vous pouvez vérifier s'il y a un e-mail pour root avec sudo mail, ou en vérifiant simplement le contenu de /var/mail/root, par exemple sudo less /var/mail/root.


Si les messages par e-mail ne vous aident pas, vérifiez également /var/log/syslog:

sudo grep CRON /var/log/syslog

Comme l'a déjà dit Alexis Wilke, cron a différents mécanismes pour définir les variables d'environnement.

Votre script a besoin de

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

dans le crontab. HOME ne devrait pas être nécessaire. Vous devriez utiliser des chemins absolus dans vos scripts, par exemple /bin/date au lieu de date. Vous pouvez trouver les bons chemins pour chaque commande avec which command_name, par exemple

$ which date
/bin/date

0voto

Cassio Seffrin Points 101

Vous pouvez ajouter cette ligne dans votre script. Ainsi, après avoir vérifié les journaux de crontab et vérifié que votre tâche a été exécutée, vous pouvez obtenir le même $PATH des crontabs.

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

Et probablement la meilleure chose à faire pour diagnostiquer les problèmes dans les scripts cron est d'obtenir toutes les variables d'environnement du système d'exploitation avec la commande env dans votre script. Il suffit d'ajouter cette ligne à votre script. Ensuite, vous pouvez analyser la sortie allEvnVars.txt

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

Une autre astuce est de diriger la sortie du script vers un endroit spécifique. Ajouter le /root/log.log. De cette façon, toute la sortie du script sera conservée dans /root/log.log

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

Vous pouvez également planifier l'exécution du script toutes les minutes pour faciliter les tests et les vérifications.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X