Pourquoi les scripts crontab ne fonctionnent pas?

Souvent, crontab les scripts ne sont pas exécutés selon le calendrier ou comme prévu. Il y a de nombreuses raisons à cela:

  1. notation crontab incorrecte
  2. problème d'autorisations
  3. variables d'environnement

Ce wiki communautaire a pour but d'agréger les principales raisons de crontab les scripts ne sont pas exécutés comme prévu. Écrivez chaque raison dans une réponse séparée.

Veuillez inclure une raison par réponse - des détails sur la raison pour laquelle il n'est pas exécuté - et des correctifs pour cette raison.

Veuillez n'écrire que des problèmes spécifiques à cron, par exemple des commandes qui s'exécutent comme prévu à partir du shell mais s'exécutent de manière erronée par cron.

Environnement différent

Cron transmet un ensemble minimal de variables d'environnement à vos tâches. Pour voir la différence, ajoutez un travail fictif comme celui-ci:

>* * * * * env / tmp/env.sortie

Attendez /tmp/env.output à créer, puis supprimez à nouveau la tâche. Maintenant, comparez le contenu de /tmp/env.output avec la sortie de env exécutez dans votre terminal habituel.

Un "gotcha" commun ici est le PATH la variable d'environnement étant différente. Peut-être que votre script cron utilise la commande somecommand trouvé dans /opt/someApp/bin, que vous avez ajouté à PATH dans /etc/environment? cron ignore PATH à partir de ce fichier, alors exécutez somecommand de votre script échouera lorsqu'il est exécuté avec cron, mais fonctionnera lorsqu'il est exécuté dans un terminal. Il convient de noter que les variables de /etc/environment sera transmis aux tâches cron, mais pas aux variables que cron se définit spécifiquement, telles que PATH.

Pour contourner cela, définissez simplement le vôtre PATH variable en haut du script. E. g.

#!/bin/bashPATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# rest of script follows

Certains préfèrent simplement utiliser des chemins absolus vers toutes les commandes à la place. Je le déconseille. Considérez ce qui se passe si vous voulez exécuter votre script sur un autre système, et sur ce système, la commande est dans /opt/someAppv2.2/bin plutôt. Vous devrez parcourir tout le script. /opt/someApp/bin avec /opt/someAppv2.2/bin au lieu de simplement faire une petite modification sur la première ligne du script.

Vous pouvez également définir la variable PATH dans le fichier crontab, qui s'appliquera à tous les travaux cron. E. g.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin15 1 * * * backupscript --incremental /home /root

My top gotcha: Si vous oubliez d'ajouter une nouvelle ligne à la fin de la crontab fichier. En d'autres termes, le fichier crontab doit se terminer par une ligne vide.

Vous trouverez ci-dessous la section pertinente des pages de manuel pour ce problème (man crontab puis passer à la fin):

   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)

Le démon Cron n'est pas en cours d'exécution. J'ai vraiment merdé avec ça il y a quelques mois.

Type:

pgrep cron 

Si vous ne voyez aucun nombre (c'est-à-dire le PID principal de cron), alors cron n'est pas en cours d'exécution. sudo /etc/init.d/cron start peut être utilisé pour démarrer cron.

EDIT: Plutôt que d'appeler des scripts d'initialisation via /etc / init.d, utilisez l'utilitaire de service, par ex.

sudo service cron start

EDIT: Vous pouvez également utiliser systemctl sous Linux moderne, par ex.

sudo systemctl start cron

Les noms des fichiers de script dans cron.d/, cron.daily/, cron.hourly/, etc., ne doit pas contenir de point (.), sinon run-parts les ignorera.

Voir les pièces de roulement(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_-]+$).

Donc, si vous avez un script cron backup.sh, analyze-logs.pl dans cron.daily/ par conséquent, vous feriez mieux de supprimer les noms d'extension.

Dans de nombreux environnements, cron exécute des commandes en utilisant sh, alors que beaucoup de gens supposent qu'il utilisera bash.

Suggestions pour tester ou corriger cela pour une commande défaillante:

  • Essayez d'exécuter la commande dans sh pour voir si ça marche:

    sh -c "mycommand"
  • Encapsulez la commande dans un sous-shell bash pour vous assurer qu'elle est exécutée dans bash:

    bash -c "mybashcommand"
  • Dites à cron d'exécuter toutes les commandes dans bash en définissant le shell en haut de votre crontab:

    SHELL=/bin/bash
  • Si la commande est un script, assurez-vous que le script contient un shebang:

    #!/bin/bash

J'ai eu quelques problèmes avec les fuseaux horaires. Cron fonctionnait avec le nouveau fuseau horaire d'installation. La solution était de redémarrer cron:

sudo service cron restart

Le chemin absolu doit être utilisé pour les scripts:

Exemple, /bin/grep devrait être utilisé à la place de grep:

# m h  dom mon dow   command0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

Au lieu de:

# m h  dom mon dow   command0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

C'est particulièrement délicat, car la même commande fonctionnera lorsqu'elle sera exécutée à partir du shell. La raison en est que cron n'a pas la même PATH variable d'environnement en tant qu'utilisateur.

Si votre commande crontab a un % symbole dedans, cron essaie de l'interpréter. Donc, si vous utilisiez une commande avec un % dans celui-ci (comme une spécification de format pour la commande date), vous devrez l'échapper.

Ça et d'autres bonnes choses ici:
http://www.pantz.org/software/cron/croninfo.html

Cron appelle un script qui n'est pas exécutable.

En courant chmod +x /path/to/script, le script devient exécutable et cela devrait résoudre ce problème.

Il est également possible que le mot de passe de l'utilisateur ait expiré. Même le mot de passe root peut expirer. Tu peux tail -f /var/log/cron.log et vous verrez cron échouer avec le mot de passe expiré. Vous pouvez définir le mot de passe pour qu'il n'expire jamais en procédant comme suit: passwd -x -1 <username>

Dans certains systèmes (Debian, Ubuntu), la journalisation pour cron n'est pas activée par défaut. Dans /etc / rsyslog.conf ou /etc / rsyslog.d / 50-défaut.conf ligne:

# cron.*                          /var/log/cron.log

devrait être édité (sudo nano /etc/rsyslog.conf) non commenté à:

cron.*                          /var/log/cron.log

Après cela, vous devez redémarrer rsyslog via

/etc/init.d/rsyslog restart

ou

service rsyslog restart 

Source: Activer la connexion crontab dans Debian Linux

Dans certains systèmes (Ubuntu), un fichier de journalisation séparé pour cron n'est pas activé par défaut, mais les journaux liés à cron apparaissent dans le fichier syslog. On peut utiliser

cat /var/log/syslog | grep cron -i

pour afficher les messages liés à cron.

Vous devez fermer ‘crontab-e’ pour que le cron prenne effet. Par exemple, en utilisant vim, j’édite le fichier et utilise: w ' pour l'écrire, mais le travail n'est pas ajouté à cron tant que je n'ai pas quitté également. Donc, je ne verrai pas le travail avant que je: q ’ aussi.

Je pense que la meilleure façon de déboguer cron est de vérifier syslog et de trouver les problèmes.

Dans mon cas - l’e-mail allait dans mon dossier SPAM, donc… vérifiez cela avant de passer des heures à déboguer :smiley:

Pannes d’électricité

Veuillez vérifier celui-ci cron - Script doesn't run via crontab but works fine standalone - Ask Ubuntu