Pourquoi les scripts crontab ne fonctionnent pas?

525

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

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

Ce wiki de communauté vise à regrouper les principales raisons pour lesquelles les crontabscripts ne sont pas exécutés comme prévu. Écris chaque raison dans une réponse distincte.

Veuillez inclure une raison par réponse - les détails sur la raison pour laquelle elle n'est pas exécutée - et corrigez le (s) problème (s) pour cette raison.

N'écrivez que les problèmes spécifiques à cron, par exemple les commandes qui s'exécutent comme prévu à partir du shell mais s'exécutent de manière erronée avec cron.

Adam Matan
la source
12
Vous devez fermer crontab -epour que le cron prenne effet. Par exemple, avec vim, je modifie le fichier et l’utilise :wpour l’écrire, mais le travail n’est pas ajouté à Cron tant que je n’ai pas quitté. Donc, je ne verrai pas le travail avant après :qaussi.
DutGRIFF le
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 allait dans mon dossier SPAM, alors ... vérifiez-le avant de passer des heures au débogage: D
almaruf
Coupures de courant
Josef Klimuk

Réponses:

501

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

Attendez /tmp/env.outputd’être créé, puis supprimez à nouveau le travail. Maintenant, comparez le contenu de /tmp/env.outputavec la sortie de envrun dans votre terminal habituel.

Un "gotcha" commun ici est que la PATHvariable d'environnement est différente. Peut-être votre script cron utilise la commande somecommandtrouvée dans /opt/someApp/bin, que vous avez ajouté à PATHen /etc/environment? cron ignore PATHce fichier, donc l'exécution somecommandde votre script échouera si elle est exécutée avec cron, mais fonctionne lorsqu'elle est exécutée dans un terminal. Il convient de noter que les variables de /etc/environmentseront transmises aux tâches cron, mais pas les variables que cron se définit spécifiquement, telles que PATH.

Pour contourner ce problème, définissez simplement votre propre PATHvariable 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 simplement utiliser des chemins absolus pour toutes les commandes. Je recommande par contre. Considérez ce qui se passe si vous souhaitez exécuter votre script sur un autre système et que sur ce système, la commande est à la /opt/someAppv2.2/binplace. Vous devrez parcourir tout le script en remplaçant /opt/someApp/binpar /opt/someAppv2.2/binau 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
geirha
la source
5
Je pense que je suis juste tombé pour ça, et que newline à la fin ... double coup dur.
WernerCD
6
+1 car envj'avais complètement oublié cette commande et je pensais que PATH fonctionnait. En fait, c'était tout à fait différent dans mon cas.
Izkata
8
@pbr Si de tels répertoires sont laissés en écriture pour d'autres, le système est déjà compromis.
geirha
6
@pbr Un administrateur système pourrait supprimer à son insu le système de fichiers racine. Vous ne pouvez pas vous prémunir contre les administrateurs système qui commettent des erreurs stupides. Si vous installez une version plus récente d'un interprète qui n'est pas compatible avec les versions antérieures, je m'attendrais à une rupture. La meilleure façon 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 en tant que python3, pas python. Et en ce qui concerne / opt / someApp / bin, pourquoi n’aurait-il pas de permissions / propriété saines? tout administrateur sensé garantirait des autorisations / propriétés saines sur les fichiers système.
geirha
2
@ pbr Il semble que nous pourrions continuer éternellement, oui. Je n'arrive toujours pas à comprendre pourquoi c'est une mauvaise idée d'utiliser PATH. Si vous avez envie d'en discuter davantage dans un média plus propice à la discussion, vous me trouverez notamment dans #ubuntu et #bash, sur irc.freenode.net
geirha le
336

Mon haut le casse-tête: Si vous oubliez d'ajouter une nouvelle ligne à la fin du crontabfichier. En d'autres termes, le fichier crontab doit se terminer par une ligne vide.

Vous trouverez ci-dessous la section appropriée dans les pages de manuel de ce problème ( man crontabpassez à 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)
utilisateur4124
la source
91
c’est un tel obstacle, comment se fait-il qu’il n’ait pas été corrigé depuis tant d’années cron?
Capi Etheriel
2
Semble être corrigé dans Vixie cron: man crontabsur Ubuntu 10.10, "cron exige que chaque entrée d'une crontab se termine par un caractère de nouvelle ligne. Si la dernière entrée d'une crontab manque de nouvelle ligne, cron considérera la crontab (au moins partiellement) comme cassée. et refuse de l'installer. " (Et la date limite est le 19 avril 2010.)
Marius Gedminas, le
19
@barraponto Il s'agit en fait d'un bogue dans les nouveaux éditeurs de texte. Le caractère "nouvelle ligne" étant censé être un caractère de fin de ligne , la dernière ligne d'un fichier texte doit se terminer par un caractère de nouvelle ligne qui n'apparaît pas dans l'éditeur. Vi et vim utilisent le personnage correctement, et cron a été construit avant que les nouveaux éditeurs ne commencent à avoir un comportement étrange ... Par conséquent, jouez-le en enregistrant une ligne vierge.
Izkata
6
Si vous modifiez crontab à l'aide, crontab -eil vérifiera la syntaxe du fichier avant de permettre une sauvegarde, y compris une vérification de la nouvelle ligne.
Tom Harrison Jr
2
@ Chan-HoSuh, selon la page de manuel "cron exige que chaque entrée d'une crontab se termine par un caractère de nouvelle ligne. Si la dernière entrée d'une crontab manque la nouvelle ligne, cron considérera que la crontab est cassée (au moins partiellement) et refuse Installez-le." Ce comportement sera invoqué lors de l'édition puis de l'enregistrement de la crontab à l'aide de l' -eoption. Il est indépendant de l'éditeur.
Tom Harrison Jr
139

Le démon Cron n'est pas en cours d'exécution. Je me suis vraiment planté avec ça il y a quelques mois.

Type:

pgrep cron 

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

EDIT: Plutôt que d’invoquer des scripts d’initialisation via /etc/init.d, utilisez l’utilitaire de service, par exemple

sudo service cron start

EDIT: Vous pouvez aussi utiliser systemctl dans Linux moderne, par exemple

sudo systemctl start cron
utilisateur6019
la source
47
Merci de me montrer pgrep. Je continuais à faire ps -ef | grep foo
ripper234
4
Vous pouvez également utiliser pidof cronqui omettra les résultats d'autres applications comportant également le mot "cron", comme crontab.
Pithikos
Bizarre, tout cela ne me donne rien pour montrer que cron est en cours d'exécution, mais si je cours, sudo service cron startje reçoisstart: Job is already running: cron
Colleen
1
service crond startsi ses centos / RHEL
Srihari Karanth
91

Le script noms de fichiers cron.d/, cron.daily/, cron.hourly/, etc., ne doivent pas contenir de point ( .), sinon run-parts seront les sauter.

Voir les run-parts (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.pldans le cron.daily/répertoire, vous feriez mieux de supprimer les noms d'extension.

Xiè Jìléi
la source
10
Il s’agit d’une fonctionnalité qui n’est pas un bug. Elle empêche les éléments tels que myscript.backup ou myscript.original ou myscript.rpm-new de s’exécuter juste à côté de myscript.
pbr le
@pbr: a du sens. Au moins, cela aurait été utile pour le débogage si run-parts --test(ou une autre option imaginaire, telle --debugque la sortie des fichiers qu’elle saute, y compris le motif).
Rabarberski
9
Si cela est une fonctionnalité, ce n'est pas une jolie. supprimez-le du répertoire "cron.d".
MatuDuke
8
C'est une si mauvaise fonctionnalité que c'est effectivement un bug. Il est courant d'exiger une fin particulière (comme ".list" ou ".cron" ou quelque chose du genre) si les gens veulent s'assurer que les choses ne se déroulent que si elles sont prévues. Choisir arbitrairement "dot" comme séparateur probable de ".bak" ou ".temp" ou autre, est complètement imprévisible, sauf dans la mesure où il déroutera de manière prévisible les gens. Les terminaisons légitimes comme ".sh" et ".pl" sont largement utilisées depuis des décennies. Cependant, beaucoup de gens utilisent "_bak" ou "_temp" ou "-bak" au lieu d'un point. Ceci est un choix de conception terrible; c'est au mieux un bug de conception.
Teekin
68

Dans de nombreux environnements, cron exécute les commandes en utilisant sh, alors que de nombreuses personnes supposent qu'il l'utilisera bash.

Suggestions pour tester ou résoudre ce problème pour une commande qui échoue:

  • Essayez d’exécuter la commande shpour voir si cela fonctionne:

    sh -c "mycommand"
    
  • Emballez 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 plaçant le shell en haut de votre crontab:

    SHELL=/bin/bash
    
  • Si la commande est un script, assurez-vous qu'il contient un shebang:

    #!/bin/bash
    
Olorin
la source
suggestion de bash est très utile, problème corrigé avec mon cron.
Maxim Galushka
Cela vient de me causer 1h de bidouillage / dépannage. Encore plus troublant si vous n’êtes pas au courant du problème, c’est que le script s’exécutera manuellement très bien si votre shell est typique bash, mais pas avec cron. Merci!
Hendy
Il y a longtemps, j'ai rencontré un problème: la commande sourceest en bash mais pas sh. Dans cron / sh, utilisez un point: . envfileplutôt que source envfile.
Kungphu
@Clockwork sh "mycommand"indique shd'exécuter mycommand en tant que fichier de script. Vouliez-vous dire sh -c "mycommand"? Quoi qu'il en soit, cette réponse semble consister à faire en sorte que la commande s'exécute spécifiquement dans bash, alors pourquoi avez-vous ajouté la commande pour shici?
Olorin le
@Olorin De mon point de vue, l'objectif du premier point était d'essayer de l'exécuter avec sh, pour voir si le problème venait vraiment du fait que cron l'exécutait avec sh au lieu de bash. Là encore, j'ai peu de connaissances sur la question, donc je peux me tromper.
Clockwork
40

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
Luissquall
la source
6
Oui, après avoir modifié le fuseau horaire d'un système, vous devez soit redémarrer chaque service qui se soucie de l'heure qu'il est ou 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é des heures sur ce point. Essayé de redémarrer le service après * * * * * touch /tmp/cronworksne rien faire, pourtant, il est RELOADà cronlog.
НЛО
36

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

Par exemple, /bin/grepdevrait être utilisé à la place 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 lorsqu’elle sera exécutée à partir d’un shell. La raison en est que cronn'a pas la même PATHvariable d'environnement que l'utilisateur.

Adam Matan
la source
3
voir geirha répondre, vous pouvez (devez) définir le PATH de cron
Capi Etheriel
9
Bzzt. vous n'avez PAS besoin de définir PATH - l'utilisation de chemins absolus est la meilleure pratique dans ce cas. "parce qu'un exécutable peut être ailleurs sur un autre ordinateur" n'a pas la valeur "Je veux qu'il exécute exactement ce programme et pas un autre que quelqu'un a mis dans le chemin devant mon programme d'origine"
pbr
1
oui ça y était pour moi, en dehors du cron je pouvais exécuter la commande directement, à l'intérieur du cron il lui fallait le /usr/bin/whateverchemin complet
Anentropic
32

Si votre commande crontab contient un %symbole, cron tente de l'interpréter. Ainsi, si vous utilisiez une commande contenant un élément %(telle qu'une spécification de format pour la commande date), vous devrez l'échapper.

Cela et d’autres bons pièges ici:
http://www.pantz.org/software/cron/croninfo.html

JMS
la source
C'est ce qui a entraîné l'échec de mon travail Cron la semaine dernière. Enfin découvert que ma date n'avait pas de caractère d'échappement (barre oblique inverse pour les autres personnes cherchant le type de personnage utilisé). Yay!
Valien
25

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

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

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

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

Sur certains systèmes (Debian, Ubuntu), la journalisation de 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) 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 journalisation crontab dans Debian Linux

Dans certains systèmes (Ubuntu), le fichier de journalisation distinct 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.

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

Si votre cronjob appelle des applications GUI, vous devez leur dire quel type d'affichage ils doivent utiliser.

Exemple: lancement de Firefox avec cron.

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

andrew
la source
aplay avait besoin de celui-ci pour une raison quelconque. merci
IljaBek
* * * * * export DISPLAY=:0 && <command>
LoMaPh
15

Les problèmes d'autorisations sont assez fréquents, j'en ai bien peur.

Notez qu'une solution de contournement courante consiste à tout exécuter à l'aide de la crontab de root, qui est parfois une très mauvaise idée. Définir des autorisations appropriées est définitivement un problème largement négligé.

utilisateur9521
la source
Notez que si vous avez une ligne crontab définie pour diriger la sortie vers un fichier qui n'existe pas encore et que le répertoire du fichier est un répertoire auquel l'utilisateur cron n'a pas accès, la ligne ne s'exécutera pas.
Evan Donovan
14

Permission non sécurisée sur la table cron

Une table cron est rejetée si son autorisation n'est pas sécurisée

sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)

Le problème est résolu avec

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs
John Peterson
la source
D'abord je l'ai compris moi-même et ensuite j'ai trouvé votre réponse! Encore merci beaucoup! Dans mon cas, j'avais inversé / restauré des crontabs dans / var / spool / cron / crontabs via SVN qui changeaient ses permissions!
Alfonx
12

Le script est sensible à l'emplacement. Ceci est lié à l'utilisation constante de chemins absolus dans un script, mais pas tout à fait la même chose. Votre tâche cron cddevra peut-être accéder à un répertoire spécifique avant d'être exécutée. Par exemple, une tâche rake sur une application Rails peut avoir besoin de se trouver à la racine de l'application pour que Rake trouve la tâche correcte, sans mentionner la configuration de base de données appropriée, etc.

Donc, une entrée crontab de

23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

serait mieux comme

23 3 * * * cd / var / www / production / current && / usr / bin / rake db: session_purge RAILS_ENV = production

Ou, pour garder l’entrée crontab plus simple et moins fragile:

23 3 * * * /home/<user>/scripts/session-purge.sh

avec le code suivant dans /home/<user>/scripts/session-purge.sh:

cd / var / www / production / actuel
/ usr / bin / rake db: session_purge RAILS_ENV = production
minute
la source
1
Si le script appelé par cron est écrit dans un langage interprété tel que PHP, vous devrez peut-être définir le répertoire de travail dans le script lui-même. Par exemple, en PHP: chdir(dirname(__FILE__));
Evan Donovan
Je viens juste de me faire prendre avec celui-ci: le script se trouvait à la racine de mon répertoire personnel, mais je l'ai ensuite déplacé (et mis à jour la crontab) et je ne pouvais pas comprendre pourquoi cela ne fonctionnait pas. Il s'avère que le script utilisait un chemin relatif, en supposant qu'il soit relatif à l'emplacement du script mais en réalité à la racine de mon répertoire personnel, car c'était le répertoire de travail que cron utilisait. C'est pourquoi le script a travaillé quand il était à la racine de mon répertoire personnel (parce que le répertoire d' un script de travail prévu et cela fonctionne juste réel est arrivé à coïncider).
Micheal Johnson
11

Les spécifications de Crontab qui ont fonctionné dans le passé peuvent casser lorsqu’elles sont déplacées d’un fichier crontab à un autre. Parfois, la raison est que vous avez déplacé la spécification d'un fichier crontab système vers un fichier crontab utilisateur ou inversement.

Le format de spécification de travail cron diffère entre les fichiers crontab des utilisateurs (/ var / spool / cron / nomutilisateur ou / var / spool / cron / crontabs / nomutilisateur) et les fichiers crontabs système ( /etc/crontabet les fichiers qu'ils contiennent /etc/cron.d).

Les crontabs du système ont un champ supplémentaire "utilisateur" juste avant la commande à exécuter.

Cela provoquera des erreurs george; command not foundlors de /etc/crontabdéclarations telles que le déplacement d'une commande ou d'un fichier dans /etc/cron.dle fichier crontab d'un utilisateur.

Inversement, cron générera des erreurs similaires /usr/bin/restartxyz is not a valid usernameou similaires lorsque l'inverse se produit.

pbr
la source
10

Le script cron appelle une commande avec l'option --verbose

Un script cron m'a échoué car j'étais en pilote automatique lors de la saisie du script et j'ai inclus l'option --verbose:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

Le script a fonctionné correctement lors de l'exécution à partir du shell, mais a échoué lors de l'exécution à partir de crontab car la sortie détaillée passe à stdout lors de l'exécution à partir du shell, mais nulle part ailleurs à partir de crontab. Solution facile pour supprimer le 'v':

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands
Aaron Peart
la source
5
Pourquoi cela cause-t-il un échec? Problèmes de tampon?
Adam Matan
Toutes les sorties ou erreurs générées via les tâches cron sont envoyées à votre boîte aux lettres. Nous ne devons jamais oublier de nous soucier de ces erreurs / sortie. Nous pouvons les rediriger vers n’importe quel fichier ou / dev / null
Nischay le
10

La raison la plus fréquente pour laquelle j'ai vu le programme cron échouer était mal programmée. Il faut de la pratique pour spécifier un travail planifié pour 23h15 au 15 23 * * *lieu de * * 11 15 *ou 11 15 * * *. Le jour de la semaine pour les travaux après minuit est également confus. MF est 2-6après minuit, non 1-5. Les dates spécifiques sont généralement un problème car nous les utilisons rarement, * * 3 1 *pas le 3 mars. Si vous n’êtes pas sûr, consultez vos plannings cron en ligne à l’ adresse https://crontab.guru/ .

Si vous travaillez avec différentes plates-formes en utilisant des options non prises en charge, telles que les 2/3spécifications temporelles, peut également entraîner des défaillances. C'est une option très utile mais non disponible universellement. J'ai également rencontré des problèmes avec des listes comme 1-5ou 1,3,5.

L'utilisation de chemins non qualifiés a également causé des problèmes. Le chemin par défaut est généralement /bin:/usr/binutilisé afin que seules les commandes standard soient exécutées. Ces répertoires n'ont généralement pas la commande souhaitée. Cela affecte également les scripts utilisant des commandes non standard. D'autres variables d'environnement peuvent également être manquantes.

Clobber entièrement une crontab existante m'a causé des problèmes. Je charge maintenant à partir d'une copie de fichier. Cela peut être récupéré à partir de la crontab existante en utilisant crontab -lsi elle est bouchée. Je garde la copie de crontab dans ~ / bin. Il est commenté tout au long et se termine par la ligne # EOF. Ceci est rechargé quotidiennement à partir d'une entrée crontab comme:

#! / usr / bin / crontab
# Recharger cette crontab
#
54 12 * * * $ {HOME} / bin / crontab

La commande de rechargement ci-dessus repose sur une crontab exécutable avec un chemin de bang exécutant crontab. Certains systèmes nécessitent la crontab en cours d'exécution dans la commande et la spécification du fichier. Si le répertoire est partagé sur le réseau, j'utilise souvent crontab.$(hostname)le nom du fichier. Cela corrigera éventuellement les cas où la mauvaise crontab est chargée sur le mauvais serveur.

L'utilisation du fichier fournit une sauvegarde de ce que devrait être la crontab, et permet aux éditions temporaires (la seule fois que j'utilise crontab -e) d'être annulées automatiquement. Des en-têtes sont disponibles pour vous aider à définir correctement les paramètres de planification. Je les ai ajoutés lorsque des utilisateurs inexpérimentés éditaient une crontab.

Rarement, j'ai rencontré des commandes nécessitant l'intervention de l'utilisateur. Celles-ci échouent sous crontab, bien que certaines fonctionnent avec la redirection d’entrée.

BillThor
la source
3
Cela couvre trois problèmes distincts. Peuvent-ils être divisés en réponses séparées?
Eliah Kagan
9
Pouvez-vous expliquer comment se 30 23 * * * traduit à 23h15?
JYelton
@JYelton C'était évidemment faux, ça devrait l'être 15 23 * * *. Corrigé maintenant.
Melebius le
7

Si vous accédez à un compte via des clés SSH, il est possible de vous connecter au compte, mais vous ne remarquerez pas que le mot de passe du compte est verrouillé (en raison d'une tentative de mot de passe périmée ou non valide, par exemple).

Si le système utilise PAM et que le compte est verrouillé, son travail cronjob peut être interrompu. (J'ai testé cela sur Solaris, mais pas sur Ubuntu)

Vous pouvez trouver des messages comme celui-ci dans / var / adm / messages:

24 oct 07:51:00 mybox cron [29024]: [ID 731128 authentification] pam_unix_account: cron essayant de valider le compte verrouillé myuser de l'hôte local
24 oct 07:52:00 mybox cron [29063]: [ID 731128 authentification] pam_unix_account: cron essayant de valider le compte verrouillé myuser de l'hôte local
24 oct 07:53:00 mybox cron [29098]: [ID 731128 authentification] pam_unix_account: cron essayant de valider le compte verrouillé myuser de l'hôte local
24 oct 07:54:00 crbox mybox [29527]: [ID 731128 auth.notice] pam_unix_account: cron tente de valider le compte verrouillé myuser de l'hôte local

Tout ce que vous devez faire est de courir:

# passwd -u <NOM D'UTILISATEUR>

en tant que root pour déverrouiller le compte, et la crontab devrait fonctionner à nouveau.

JohnGH
la source
7

Si vous avez une commande comme celle-ci:

* * * * * /path/to/script >> /tmp/output

et cela ne fonctionne pas et vous ne voyez aucune sortie, cela ne signifie pas nécessairement que cron ne fonctionne pas. Le script pourrait être cassé et la sortie irait à stderr qui ne serait pas passée à / tmp / output. Vérifiez que ce n'est pas le cas, en capturant également cette sortie:

* * * * * /path/to/script >> /tmp/output 2>&1

pour voir si cela vous aide à résoudre votre problème.

Philluminati
la source
3

=== Alerte Docker ===

Si vous utilisez docker,

Je pense qu'il convient d'ajouter que je n'ai pas réussi à faire fonctionner cron en tâche de fond.

Pour exécuter un travail cron à l'intérieur du conteneur, j'ai utilisé superviseur et exécuté cron -favec l'autre processus.

Edit: Un autre problème - Je n'ai pas non plus réussi à le faire fonctionner lors de l'exécution du conteneur avec la mise en réseau HOST. Voir ce numéro ici aussi: https://github.com/phusion/baseimage-docker/issues/144

AlonL
la source
3

J'écrivais un script shell d'installation qui crée un autre script pour purger les anciennes données de transaction d'une base de données. Dans le cadre de cette tâche, il devait configurer le crontravail quotidien pour s’exécuter à une heure arbitraire, lorsque la charge de la base de données était faible.

J'ai créé un fichier mycronjobavec le programme cron, le nom d'utilisateur et la commande et l' ai copié dans le /etc/cron.drépertoire. Mes deux pièges:

  1. mycronjob le fichier devait appartenir à root pour être exécuté
  2. Je devais définir les autorisations du fichier sur 644 - 664 ne fonctionneraient pas.

Un problème d'autorisation apparaîtra /var/log/syslogcomme quelque chose de similaire à:

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)

La première ligne fait référence à /etc/crontabfichier et la dernière à un fichier que j'ai placé sous /etc/cront.d.

Izik Golan
la source
2

La ligne écrite d'une manière que crontab ne comprend pas. Il doit être correctement écrit. Voici CrontabHowTo .

Kangarooo
la source
1
Comment cela peut-il être débogué?
Adam Matan
Consulter le journal des erreurs de cron est le moyen le plus courant. IIRC 'crontab -e' effectue une analyse syntaxique après avoir également modifié le fichier - mais cela peut ne pas être universel.
pbr le
2

Le démon Cron peut être en cours d'exécution, mais ne fonctionne pas réellement. Essayez de redémarrer cron:

sudo /etc/init.d/cron restart
Phil Dodd
la source
3
Je n'ai jamais vu ce cas en production. Cela ne veut pas dire que cela ne s'est pas produit - mais que je ne l'ai pas vu depuis 30 ans que j'utilise UNIX et Linux. Cron est incroyablement robuste.
pbr le
1
Je ne suis pas sûr, mais je pense que cela m'est vraiment arrivé. J'ai essayé pidofcron et je n'ai rien eu. Essayé d'utiliser l' serviceutilitaire et il a été dit que cron fonctionnait déjà. Il suffit d'exécuter cette commande et de l'exécuter à pidofnouveau et j'obtiens un résultat.
Colleen
2

Ecrire dans cron via "crontab -e" avec l'argument nom d'utilisateur dans une ligne. J'ai vu des exemples d'utilisateurs (ou d'administrateurs système) écrivant leurs scripts shell sans comprendre pourquoi ils ne s'automatisaient pas. L'argument "utilisateur" existe dans / etc / crontab, mais pas dans les fichiers définis par l'utilisateur. Ainsi, par exemple, votre dossier personnel serait quelque chose comme:

# m h dom mon dow command

* * */2  *   *  /some/shell/script

alors que / etc / crontab serait:

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

Alors, pourquoi voudriez-vous faire le dernier? En fonction de la manière dont vous souhaitez définir vos autorisations, cela peut devenir très compliqué. J'ai écrit des scripts pour automatiser des tâches destinées à des utilisateurs qui ne comprennent pas les subtilités ou qui ne veulent pas s'embarrasser de tâches fastidieuses. En définissant les autorisations sur --x------, je peux rendre le script exécutable sans que ceux-ci puissent le lire (et peut-être le modifier accidentellement). Cependant, je souhaiterais peut-être exécuter cette commande avec plusieurs autres d'un fichier (ce qui facilitera sa maintenance), mais assurez-vous que le bon propriétaire du fichier est attribué à la sortie du fichier. Cela (du moins dans Ubuntu 10.10) interrompt à la fois l’impossibilité de lire et d’exécuter le fichier, ainsi que le problème mentionné précédemment avec la mise de périodes dans / etc / crontab (ce qui, assez curieusement, ne cause aucune erreur lors du passage crontab -e). .

Par exemple, j'ai vu des exemples de personnes ayant l' sudo crontab -ehabitude d'exécuter un script avec des autorisations root, avec une correspondance chown username file_outputdans le script shell. Sloppy, mais ça marche. IMHO, l'option la plus gracieuse est de le mettre /etc/crontabavec le nom d'utilisateur déclaré et les autorisations appropriées, pour file_outputaller au bon endroit et au bon propriétaire.

Mange
la source
« Ce faisant, (au moins dans Ubuntu 10.10) se brise à la fois l'incapacité de lire le fichier, ainsi que d' exécuter ..... » Je dois préciser: / etc / crontab (par défaut) EXIGE lecture et d' exécution, alors que vous pourriez exécutez "sudo crontab -e" pour créer un travail cron qui remplace à la fois le besoin de l'autorisation "w" et le problème posé par les extensions telles que ".sh". Je n'ai pas eu le temps de séparer le code cron et de vérifier pourquoi cela fonctionne, juste un détail que j'ai remarqué.
Mange
2

En se basant sur ce que Aaron Peart a mentionné à propos du mode commenté, des scripts qui ne sont pas en mode commenté s’initialisent mais ne se terminent pas si le comportement par défaut d’une commande incluse consiste à afficher une ou plusieurs lignes à l’écran une fois le processus lancé. Par exemple, j’ai écrit pour notre intranet un script de sauvegarde qui utilisait curl, un utilitaire qui télécharge ou télécharge des fichiers sur des serveurs distants. C’est très pratique si vous ne pouvez accéder auxdits fichiers distants que via HTTP. L'utilisation de 'curl http://something.com/somefile.xls ' provoquait le blocage d'un script que j'avais écrit et qui ne finissait jamais car il créait une nouvelle ligne suivie d'une ligne de progression. Je devais utiliser le drapeau silencieux (-s) pour lui dire de ne donner aucune information et écrire dans mon propre code pour le gérer si le téléchargement du fichier échouait.

Gale
la source
1
Pour les programmes qui n'ont pas un mode silencieux, vous pouvez rediriger leur sortie vers /dev/null. Par exemple: some-command > /dev/nullCeci redirigera uniquement la sortie standard, et non la sortie d'erreur (qui correspond généralement à ce que vous souhaitez, puisque vous souhaitez être informé des erreurs). Pour rediriger aussi la sortie d'erreur, utilisez some-command &> /dev/null.
Eliah Kagan
Oui, c’était ma première pensée lors de l’écriture du script susmentionné. J'oublie pourquoi je ne l'ai pas utilisé, peut-être un comportement non standard qui a contourné ladite solution. Je sais que le mode verbose / interactif est le mode par défaut de certaines commandes (je vous regarde, scp!), Ce qui signifie que vous devez ignorer la sortie pour un fonctionnement sans problème des scripts shell.
Mange
2

Bien que vous puissiez définir des variables d'environnement dans votre crontable, vous n'êtes pas dans un script shell. Donc, des constructions comme celles-ci ne fonctionneront pas:

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

En effet, les variables ne sont pas interprétées dans la crontable: toutes les valeurs sont prises littéralement. Et c'est pareil si vous omettez les crochets. Ainsi, vos commandes ne seront pas exécutées et vos fichiers journaux ne seront pas écrits ...

Au lieu de cela, vous devez définir toutes vos variables d'environnement directement:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}
Alexandre
la source
2

Lorsqu'une tâche est exécutée dans cron, stdin est fermé. Les programmes qui agissent différemment selon que stdin est disponible ou non se comporteront différemment entre la session shell et in cron.

Un exemple est le programme goaccessd'analyse des fichiers journaux du serveur Web. Cela ne marche PAS dans cron:

goaccess -a -f /var/log/nginx/access.log > output.html

et goaccessaffiche la page d'aide au lieu de créer le rapport. Dans la coque, ceci peut être reproduit avec

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

Le correctif goaccessest de le faire lire le journal depuis stdin au lieu de le lire dans le fichier. La solution consiste donc à modifier l’entrée crontab en

cat /var/log/nginx/access.log | goaccess -a > output.html
Martijn de Milliano
la source
2

Dans mon cas, cron et crontab avaient des propriétaires différents.

Je ne travaillais pas, j'avais ceci:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

En gros, je devais exécuter cron-config et répondre correctement aux questions. À un moment donné, il m'a été demandé de saisir mon mot de passe d'utilisateur Win7 pour mon compte "Utilisateur". D'après ce que j'ai lu, il semble que ce soit un problème de sécurité potentiel, mais je suis le seul administrateur sur un seul réseau domestique et j'ai donc décidé que tout allait bien.

Voici la séquence de commande qui m'a permis de continuer:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to [email protected].
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $
KiloOne
la source
1
Bien que bien documenté, cela ressemble à un point spécifique à Cygwin; appartient-il vraiment à askubuntu?
sxc731
2

Sur mes serveurs RHEL7, les travaux root cron s'exécutent, mais pas les travaux utilisateur. J'ai trouvé que sans un répertoire personnel, les travaux ne s'exécuteraient pas (mais vous verrez de bonnes erreurs dans / var / log / cron). Lorsque j'ai créé le répertoire personnel, le problème a été résolu.

Dennis Parslow
la source
2

Si vous avez modifié votre fichier crontab à l'aide d'un éditeur Windows (via samba ou quelque chose de ce genre) et qu'il a remplacé les nouvelles lignes par \ n \ r ou simplement \ r, cron ne s'exécutera pas.

De plus, si vous utilisez /etc/cron.d/* et que l'un de ces fichiers contient un \ r, cron se déplacera dans les fichiers et s'arrêtera lorsqu'il détecte un fichier endommagé. Vous ne savez pas si c'est le problème?

Utilisation:

od -c /etc/cron.d/* | grep \r
Doug
la source