Question Pourquoi les scripts crontab ne fonctionnent pas?


Souvent, crontab les scripts ne sont pas exécutés comme prévu ou comme prévu. Les raisons sont multiples:

  1. mauvaise notation crontab
  2. problème de permissions
  3. Variables d'environnement

Ce wiki de communauté vise à regrouper 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 elle n’a pas été exécutée - et des corrections pour cette raison.

S'il vous plaît écrivez seulement des problèmes spécifiques à cron, par ex. les commandes qui s'exécutent comme prévu à partir du shell mais s'exécutent de manière erronée par cron.


454


origine


Vous devez fermer crontab -e pour que le cron prenne effet. Par exemple, en utilisant vim, je modifie le fichier et utilise :w pour l'écrire mais le travail n'est pas ajouté à cron jusqu'à ce que je quitte aussi. Donc je ne verrai pas le travail avant que je :q aussi. - DutGRIFF
Je pense que le meilleur moyen de déboguer Cron est de vérifier syslog et de trouver les problèmes. - Suneel Kumar
Dans mon cas - l’e-mail était envoyé dans mon dossier SPAM, alors vérifiez bien avant de passer des heures sur le débogage: D - almaruf
Coupures d'électricité - Josef Klimuk


Réponses:


Environnement différent

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

* * * * * env> /tmp/env.output

Attendre /tmp/env.output être créé, puis supprimez le travail à nouveau. Maintenant, comparez le contenu de /tmp/env.output avec la sortie de env courir dans votre terminal habituel.

Un "gotcha" commun est la PATH variable d'environnement différente. Peut-être que votre script cron utilise la commande somecommand trouvé dans /opt/someApp/bin, auquel vous avez ajouté PATH dans /etc/environment? cron ignore PATH à partir de ce fichier, donc runnning 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 les variables cron se définissent, comme par exemple PATH.

Pour contourner ce problème, définissez votre propre PATH variable en haut du script. Par exemple.

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

Certains préfèrent utiliser uniquement des chemins absolus à toutes les commandes. Je recommande contre cela. 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 au lieu. Vous devriez passer par tout le script en remplaçant /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. Par exemple.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

431



Je pense que je suis juste tombé pour ça, et je reviens à la fin ... double whammy. - WernerCD
+1 pour env, J'avais complètement oublié cette commande et je pensais que PATH travaillait. C’était en fait très différent dans mon cas. - Izkata
@pbr Si de tels répertoires sont accessibles en écriture, le système est déjà compromis. - geirha
@pbr Un administrateur pourrait supprimer involontairement le système de fichiers racine. Vous ne pouvez pas empêcher les administrateurs système de commettre des erreurs stupides. Si vous installez une version plus récente d'un interpréteur qui n'est pas rétrocompatible, je m'attendrais à une casse de toute façon. La manière saine de gérer cela consiste à l'installer en tant que commande différente. Par exemple. vous avez la version 2.x de python et installez python 3, vous l'installez comme python3, pas python. Et pour ce qui est de / opt / someApp / bin, pourquoi n'aurait-il pas des droits / propriété sains? tout administrateur sain devrait garantir des autorisations / droits de propriété sains sur les fichiers système. - geirha
@pbr Il semble que nous pourrions continuer pour toujours, oui. Je ne vois toujours pas pourquoi utiliser PATH est une mauvaise idée. Si vous avez envie de discuter de cela plus avant dans un support plus adapté à la discussion, vous me trouverez entre autres sur #ubuntu et #bash sur irc.freenode.net - geirha


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

Vous trouverez ci-dessous la section correspondante dans les pages de manuel relatives à ce problème (man crontab puis passez à 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)

291



C’est un vrai spectacle, comment se fait-il qu’il n’ait pas été réparé depuis tant d’années de cron? - Capi Etheriel
Semble être corrigé dans Vixie cron: man crontab sur Ubuntu 10.10 dit "cron nécessite que chaque entrée dans un crontab se termine par un caractère de nouvelle ligne. Si la dernière entrée dans une crontab manque la nouvelle ligne, cron considérera la crontab (au moins partiellement) cassée et refusera de l'installer." (Et la date à la fin est le 19 avril 2010.) - Marius Gedminas
@barraponto Ceci est en fait un bug dans les nouveaux éditeurs de texte. Le caractère "newline" est censé être un terminaison de ligne caractère, donc la dernière ligne dans un fichier texte est censée se terminer par un caractère de nouvelle ligne qui ne s'affiche pas dans l'éditeur. Vi et vim utilisent le caractère correctement, et cron a été créé avant que les nouveaux éditeurs ne commencent leur comportement étrange ... Il est donc possible de le sauvegarder et d'inclure une ligne vide. - Izkata
Si vous modifiez crontab en utilisant crontab -e il vérifiera la syntaxe du fichier avant d'autoriser une sauvegarde, y compris une vérification de la nouvelle ligne. - Tom Harrison Jr
@ Chan-HoSuh, selon la page de manuel "cron nécessite que chaque entrée dans un crontab se termine par un caractère de nouvelle ligne. Si la dernière entrée d'un crontab manque la nouvelle ligne, cron considérera la crontab (au moins partiellement) cassée et refusera Installez-le." Ce comportement sera invoqué lors de l’édition puis de la sauvegarde de la crontab à l’aide du -e option, et est indépendant de l'éditeur. - Tom Harrison Jr


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

Type:

pgrep cron 

Si vous ne voyez aucun numéro, alors cron ne fonctionne pas. sudo /etc/init.d/cron start peut être utilisé pour démarrer cron.

EDIT: Plutôt que d’invoquer les scripts d’initialisation via /etc/init.d, utilisez le service utilitaire, par ex.

sudo service cron start

125



Merci de m'avoir montré pgrep. J'ai continué à faire ps -ef | grep foo - ripper234
Vous pouvez aussi utiliser pidof cron qui omettra les résultats pour les autres applications qui ont également le mot «cron», comme crontab. - Pithikos
Bizarre, tout cela ne me donne rien à montrer cron est en cours d'exécution, mais si je cours sudo service cron start Je reçois start: Job is already running: cron - Colleen
service crond start si son centos / RHEL - Srihari Karanth


Les noms de fichier du script dans cron.d/, cron.daily/, cron.hourly/, etc., ne doit pas contenir de point (.), sinon les parties d'exécution les ignorent.

Voir les parties d'exécution (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/ répertoire, vous feriez mieux de supprimer les noms d'extension.


83



C'est une fonctionnalité et non un bogue - elle empêche l'exécution de myscript.backup, myscript.original ou myscript.rpm-new à côté de myscript. - pbr
@pbr: a du sens. Au moins, cela aurait été utile pour le débogage si run-parts --test (ou une autre option imaginaire comme --debug produirait les fichiers qu'il saute, y compris la raison. - Rabarberski
S'il s'agit d'une fonctionnalité, ce n'est pas une fonctionnalité intéressante :( Beaucoup de personnes utilisent un nom de fichier pointillé (backup.sh est le plus courant). Si vous souhaitez qu'un script cesse de s'exécuter, la méthode la plus logique sera de supprimez-le du répertoire "cron.d". - MatuDuke
C'est une si mauvaise caractéristique que c'est effectivement un bogue. Il est courant d'exiger une fin particulière (comme ".list" ou ".cron" ou autre) si les utilisateurs veulent s'assurer que les choses ne sont exécutées que lorsqu'elles sont prévues. Choisir arbitrairement un point comme séparateur probable pour ".bak" ou ".temp" ou autre, est complètement imprévisible, sauf dans la mesure où cela risque de créer une confusion chez les gens. Des fins légitimes comme ".sh" et ".pl" sont largement utilisées depuis des décennies. Beaucoup de gens utilisent "_bak" ou "_temp" ou "-bak" au lieu d'un point. Ceci est un choix de conception terrible; c'est un bug de conception au mieux. - Teekin


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 ceci pour une commande défaillante:

  • Essayez de lancer la commande dans sh pour voir si ça marche
  • Enveloppez 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 en 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

55



La suggestion de bash est très utile, corrige le problème avec mon cron. - Maxim Galushka
Cela m'a juste causé 1h de violon / dépannage. Encore plus surprenant si vous n'êtes pas au courant du problème est que le script s'exécute manuellement si vous êtes un shell typique bash, mais pas avec cron. Merci! - Hendy
Il y a longtemps, j'ai rencontré quelque chose de apparenté: la commande source est en bash mais pas sh. Dans cron / sh, utilisez un point: . envfile plutôt que source envfile. - kungphu


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

34



Oui, après avoir modifié le fuseau horaire sur un système, vous devez soit redémarrer chaque service concerné, soit redémarrer. Je préfère le redémarrage, pour être sûr d'avoir tout attrapé. - pbr
Oh pour l'amour de Dieu, tu as tué des heures là-dessus. Essayé service redémarrer après * * * * * touch /tmp/cronworks n'a rien fait, pourtant il y a RELOAD à cronlog. - НЛО


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 à la commande date), vous devrez y échapper.

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


29



C'est ce qui a causé l'échec de mon travail Cron la semaine dernière. Finalement, j'ai compris que mon Date n'avait pas de caractère d'échappement (barre oblique inverse pour les autres personnes à la recherche du caractère d'échappement). Yay! - Valien
Voir également Comment puis-je exécuter date à l'intérieur d'un travail de tabulation cron? - Jared Beck
Celui-ci m'a mordu aussi. Merci! - stefansundin


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

Par exemple, /bin/grep devrait être utilisé au lieu de grep:

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

Au lieu de:

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

Ceci est particulièrement délicat, car la même commande fonctionnera à partir du shell. La raison en est que cron n'a pas le même PATH variable d'environnement en tant qu'utilisateur.


28



voir la réponse de geirha, vous pouvez (devez) définir le PATH de cron - Capi Etheriel
Bzzt. vous n'avez pas besoin de définir le PATH - utiliser les chemins absolus est la meilleure pratique ici. "parce qu'un exécutable est peut-être ailleurs sur un autre ordinateur" ne l'emporte pas "je veux qu'il exécute exactement ce programme et pas un autre que quelqu'un ait mis le chemin devant mon programme d'origine" - pbr
oui, c’était ça pour moi, en dehors du cron, je pouvais exécuter la commande directement, à l’intérieur du cron /usr/bin/whatever chemin - Anentropic


Il est également possible que le mot de passe de l'utilisateur ait expiré. Même le mot de passe root peut expirer. Vous pouvez tail -f /var/log/cron.log et vous verrez cron fail avec le mot de passe expiré. Vous pouvez définir le mot de passe pour ne jamais expirer 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-default.conf la ligne:

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

devrait être édité (sudo nano /etc/rsyslog.conf) sans commentaire:

cron.*                          /var/log/cron.log

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

/etc/init.d/rsyslog restart

ou

service rsyslog restart 

La source: Activer la journalisation crontab dans Linux Debian

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

cat /var/log/syslog | grep cron

pour afficher les messages liés à cron.


23



J'ai Debian (Wheezy) mais il n'y a pas /etc/init.d/rsyslog, seulement inetutils-syslogd et sysklogd. Dois-je installer quelque chose ou simplement redémarrer l'un des deux? - hgoebl


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

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


21



Ce n'est pas unique à cron, et facilement traçable en essayant simplement d'exécuter /path/to/script à partir de la ligne de commande. - Adam Matan
Si vous avez l'habitude d'exécuter des scripts avec . scriptname ou sh scriptname ou bash scriptname, alors cela devient un cronproblème spécifique. - Eliah Kagan


Si votre tâche invoque des applications GUI, vous devez leur indiquer quel AFFICHAGE ils doivent utiliser.

Exemple: Firefox lance avec cron.

Votre script devrait contenir export DISPLAY=:0 quelque part.


16



Aplay avait besoin de celui-ci pour une raison quelconque. Je vous remercie - IljaBek
* * * * * export DISPLAY=:0 && <command> - LoMaPh