Comment configurer correctement un travail root cron


36

J'ai essayé de configurer un travail racine pour exécuter un script Bash en tant que root, afin qu'il s'exécute à la minute 7,37, toutes les heures, tous les jours du mois, tous les mois. Ce script est situé dans /usr/binet 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 appelé, le script écrit ce qui se passe dans un journal situé dans /var/log/tunlr.log

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

sudo crontab -e

Et inséré ces 2 lignes à la fin. Je m'attends à ce que cron exécute le script en tant que 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

Une commande ultérieure a sudo crontab -lconfirmé que le travail cron a été inséré.

J'ai redémarré Ubuntu et je vérifiais dans le fichier journal si le travail cron avait été lancé correctement. Cependant, rien dans le fichier journal ne /var/log/tunlr.logsignifie que le travail n'a jamais été lancé avec succès.

J'ai vérifié que si j'exécutais le script à partir de la ligne de commande

sudo /usr/bin/tunlrupdate.sh

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

Pourquoi cette tâche cron ne fonctionne-t-elle pas comme prévu dans mon système?

MISE À JOUR 1: Toutes les solutions proposées à ce jour ne fonctionnent pas. Je remercie Olli d’un CLI pour répertorier le journal du système sudo grep CRON /var/log/syslog. Cependant, j'ai eu 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 le PATH suggéré = insertion et utilisation du chemin absolu depuis la racine pour les fonctions du script ou sans les solutions suggérées ici. J'ai toujours cette erreur.

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

Puis lister le journal des erreurs CRON dans 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 n'arrive toujours pas à exécuter le script bash. Cette fois, aucune erreur n'est affichée dans le journal. Pour avoir l’assurance 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 le job cron. Rien n'est écrit dans le fichier journal. Donc, même un script vide peut ne pas être exécuté dans cron? Je ne comprends pas. Je sais essayer un script réduit à ces 2 lignes:

#!/bin/bash
exit 0

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


Si vous voulez que ce soit un cronjob "racine", vous devez être root, puis vous tapez crontab -e. De plus, il vous suffit de vous connecter en tant que root (type de console "su root"), puis de crontab -e (sudo n'est pas nécessaire dans ce cas).
Wolfgang

Bien. Je ne vois pas le but de votre réponse? Taper $ sudo crontab -e a fait le travail comme indiqué par $ sudo crontab -l, c’est-à-dire que la ligne décrivant le nouveau travail a été ajoutée au cron de la racine. En tant que tel, le travail n'est pas présent dans l'utilisateur cron. Par exemple, $ crontab -l ne montre aucun travail cron ajouté ici.
Antonio

@WolfgangVogl il a utilisé "sudo" qui fonctionne comme prévu.
Alexis Wilke

Réponses:


68

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 voulez exécuter votre script en tant que root :

sudo crontab -e

Et ajoutez la même ligne:

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

@NineCattoRules Si vous ne perdez pas la sortie, que voyez-vous?
Angelo Fuchs

@AngeloFuchs old comment ... J'ai sûrement essayé cette commande en tant que root ( sudo crontab -eau lieu de crontab -e). Ou quelque chose d'autre, de toute façon cela fonctionne
NineCattoRules

10

Enfin, la solution de travail. Dans le syslog, j'ai vu l'intrépide et répétitif:

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

Cela ressemble à la racine n'a pas été reconnu comme un cmd. Comme j'ai déjà utilisé le cron de la racine en utilisant $ sudo /usr/bin/tunlrupdate.sh. Ensuite, j'ai essayé avec le script d'origine (corrigé pour une erreur dans la date UNIX cmd:% m qui est le mois a été utilisé pour les minutes qui est% M) ce qui suit (qui supprime la racine de la ligne 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

Cela s'est avéré être la solution finale. [Bien que j'ai trouvé de nombreux ouvrages indiquant la ligne erronée avec la racine dans la ligne cron. C'était une erreur].


Bon point Olli. Je suis d'accord avec toi là-dessus. Pour référence, la crontab utilisateur est stockée dans / var / spool / cron / crontabs / nom-utilisateur ou pour root / var / spool / cron / crontabs / root. Voir cette page askubuntu.com/questions/216692/where-is-the-user-crontab-stored Le dossier contenant est déjà et donne le nom de l'utilisateur.
Antonio

Eh bien, vous ne devriez pas avoir besoin de cette information, car vous ne devriez éditer que les fichiers crontab avec crontabcommande (sauf les fichiers crontab sous /etc).
Olli

1
@Antonio, les scores avec le champ nom d'utilisateur ne sont utilisés que dans /etc/crontab(la crontab du système). En utilisant sudo crontab -evotre travail avec la crontab de root qui peut généralement être trouvée dans/var/spool/cron/crontabs
Matijs le

2

Un "problème" avec cron est le manque de variables d’environnement (pour des raisons évidentes de sécurité). Il vous manque probablement PATH et HOME. Vous pouvez définir ceux-ci dans le script directement ou dans le fichier 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

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


1
C'est la seule réponse ici qui a réellement fonctionné pour moi. J'ai copié les instructions SHELL et PATH à partir du /etc/crontabfichier et les ai collées dans le sudo crontab -eet la commande a été exécutée en tant que root sans problème. Merci!
Terrance

0

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


Si les courriels ne vous aident pas, vérifiez également /var/log/syslog:

sudo grep CRON /var/log/syslog

Comme Alexis Wilke l'a déjà dit, les mécanismes cron permettent de définir des variables d'environnement.

Votre script a besoin

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

à la crontab. HOMEne devrait pas être nécessaire. Vous devez utiliser des chemins absolus dans vos scripts, par exemple à la /bin/dateplace de date. Vous pouvez trouver les chemins appropriés pour chaque commande avec which command_name, par exemple

$ which date
/bin/date

Exécuter votre suggestion de grep CRON dans / var / log / syslog Je me suis trompé le 11 février 14:37:01 Marius-PC CRON [7826]: (racine) CMD (racine /usr/bin/tunlrupdate.sh) 11 février 14 37:01 Marius-PC CRON [7825]: (racine) MAIL (1 octet de sortie envoyé, mais ayant le statut 0x00ff, # 012) 11 février 14:39:01 Marius-PC CRON [7849]: (racine) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] && trouver / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -type f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -elelete) Si j'ajoute quelques définitions pour le PATH dans le cron, celles-ci n'affecteront pas mon système $ PATH?
Antonio

Cette sortie indique qu'elle a essayé d'envoyer un message par courrier électronique mais qu'elle a échoué. Cela signifie que vous ne recevez pas ce message d'erreur /var/mail/root. Vous pouvez résoudre ce problème ou essayer avecPATH=...
Olli

@Antonio, au lieu d'utiliser cette version patchée
Olli

Merci. Je sais que je n'ai pas configuré la messagerie électronique du système et je savais que cela n'avait pas abouti. J'avais déjà modifié le script pour utiliser le chemin absolu pour toute fonction appelée. La dernière chose était ma question précédente: une définition de PATH dans crontab ne va-t-elle pas perturber ma variable système $ PATH?
Antonio

1
Entre-temps, j'étais occupé à corriger un bogue au format de date à partir du script d'origine. Il utilisait% m (ce qui correspond au mois et NON à la minute) au lieu de% M ...
Antonio

0

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

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

Et la meilleure chose à faire pour diagnostiquer les problèmes dans les scripts cron est d’obtenir toutes les variables d’environnement de SO avec la commande env dans votre script. Il suffit donc d'ajouter cette ligne à votre script. Ensuite, vous pouvez analyser la sortieallEvnVars.txt

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

Une autre astuce consiste à diriger la sortie du script vers un endroit quelconque. Ajout du /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 programmer le script pour qu'il exécute chaque minute afin de faciliter les tests et les vérifications.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.