GNU/Linux >> Tutoriels Linux >  >> Linux

CronJob ne fonctionne pas

WTF ? ! Mon cronjob ne s'exécute pas ? !

Voici un guide de liste de contrôle pour déboguer sans exécuter les cronjobs :

  1. Le démon Cron est-il en cours d'exécution ?
  • Exécuter ps ax | grep cron et recherchez cron.
  • Debian :service cron start ou service cron restart
  1. Cron fonctionne-t-il ?
  • * * * * * /bin/echo "cron works" >> /tmp/file
  • Syntaxe correcte ? Voir ci-dessous.
  • Vous devez évidemment avoir un accès en écriture au fichier vers lequel vous redirigez la sortie. Un nom de fichier unique en /tmp qui n'existe pas actuellement doit toujours être accessible en écriture.
  • Ajouter probablement aussi 2>&1 pour inclure l'erreur standard ainsi que la sortie standard, ou sortir séparément l'erreur standard dans un autre fichier avec 2>>/tmp/errors
  1. La commande fonctionne-t-elle de manière autonome ?
  • Vérifiez si le script contient une erreur en effectuant un essai sur la CLI
  • Lorsque vous testez votre commande, testez en tant qu'utilisateur dont vous modifiez la crontab, qui peut ne pas être votre login ou root
  1. Cron peut-il exécuter votre tâche ?
  • Vérifier /var/log/cron.log ou /var/log/messages pour les erreurs.
  • Ubuntu :grep CRON /var/log/syslog
  • Redhat :/var/log/cron
  1. Vérifier les autorisations
  • Définir l'indicateur d'exécutable sur la commande :chmod +x /var/www/app/cron/do-stuff.php
  • Si vous redirigez la sortie de votre commande vers un fichier, vérifiez que vous êtes autorisé à écrire dans ce fichier/répertoire
  1. Vérifier les chemins
  • Vérifier la ligne she-bangs/hashbangs
  • Ne vous fiez pas aux variables d'environnement comme PATH , car leur valeur ne sera probablement pas la même sous cron que sous une session interactive. Voir Comment faire en sorte que CRON appelle les bons PATH
  1. Ne supprimez pas la sortie pendant le débogage
  • Cette suppression est couramment utilisée :30 1 * * * command > /dev/null 2>&1
  • Réactivez la sortie standard ou la sortie de message d'erreur standard en supprimant >/dev/null 2>&1 tout à fait; ou peut-être rediriger vers un fichier dans un emplacement où vous avez un accès en écriture :>>cron.out 2>&1 ajoutera la sortie standard et l'erreur standard à cron.out dans le répertoire personnel de l'utilisateur appelant.
  • Si vous ne redirigez pas la sortie d'un cron job, le démon essaiera de vous envoyer tout message de sortie ou d'erreur par e-mail. Vérifiez votre boîte de réception (peut-être simplement more $MAIL si vous n'avez pas de client de messagerie). Si le courrier n'est pas disponible, recherchez peut-être un fichier nommé dead.letter dans votre répertoire personnel ou des entrées de journal système indiquant que la sortie a été supprimée. Surtout dans ce dernier cas, éditez probablement la tâche pour ajouter une redirection vers un fichier, puis attendez que la tâche s'exécute et examinez le fichier journal à la recherche de messages d'erreur ou d'autres commentaires utiles.
  • Si vous essayez de comprendre pourquoi quelque chose a échoué, les messages d'erreur seront visibles dans ce fichier. Lisez-le et comprenez-le.

Ne fonctionne toujours pas ? Aïe !

  1. Augmenter le niveau de débogage cron
  • Debian
    • en /etc/default/cron
    • définir EXTRA_OPTS="-L 2"
    • service cron restart
    • tail -f /var/log/syslog pour voir les scripts exécutés
  • Ubuntu
    • en /etc/rsyslog.d/50-default.conf
    • ajouter ou commenter la ligne cron.* /var/log/cron.log
    • recharger l'enregistreur sudo /etc/init.d/rsyslog restart
    • réexécuter cron
    • ouvrir /var/log/cron.log et recherchez une sortie d'erreur détaillée
  • Rappel :désactivez le niveau de journalisation lorsque vous avez terminé le débogage
  1. Exécutez cron et vérifiez à nouveau les fichiers journaux

Syntaxe des tâches cron

# Minute  Hour  Day of Month      Month         Day of Week    User Command    
# (0-59) (0-23)   (1-31)    (1-12 or Jan-Dec) (0-6 or Sun-Sat)  
         
    0       2       *             *                *          root /usr/bin/find

Cette syntaxe est seulement correct pour le root utilisateur. Utilisateur régulier crontab la syntaxe n'a pas le Utilisateur champ (les utilisateurs réguliers ne sont pas autorisés à exécuter du code comme n'importe quel autre utilisateur) ;

# Minute  Hour  Day of Month      Month         Day of Week    Command    
# (0-59) (0-23)   (1-31)    (1-12 or Jan-Dec) (0-6 or Sun-Sat)  
         
    0       2       *             *                *          /usr/bin/find

Commandes Crontab

  1. crontab -l
    • Répertorie toutes les tâches cron de l'utilisateur.
  2. crontab -e , pour un utilisateur spécifique :crontab -e -u agentsmith
    • Démarre la session d'édition de votre fichier crontab.
    • Lorsque vous quittez l'éditeur, la crontab modifiée est automatiquement installée.
  3. crontab -r
    • Supprime votre entrée crontab du spouleur cron, mais pas du fichier crontab.

Je veux ajouter 2 points que j'ai appris :

  1. Les fichiers de configuration Cron placés dans /etc/cron.d/ ne doivent pas contenir de point (.). Sinon, il ne sera pas lu par cron.
  2. Si l'utilisateur qui exécute votre commande n'est pas dans /etc/shadow. Il ne sera pas autorisé à programmer cron.

Références :

  1. http://manpages.ubuntu.com/manpages/xenial/en/man8/cron.8.html
  2. https://help.ubuntu.com/community/CronHowto

Enfin j'ai trouvé la solution. Voici la solution :-

  1. N'utilisez jamais de chemin relatif dans les scripts python à exécuter via crontab. J'ai fait quelque chose comme ceci à la place :-

    import os
    import sys
    import time, datetime
    
    CLASS_PATH = '/srv/www/live/mainapp/classes'
    SETTINGS_PATH = '/srv/www/live/foodtrade'
    sys.path.insert(0, CLASS_PATH)
    sys.path.insert(1,SETTINGS_PATH)
    
    import other_py_files
    
  2. Ne supprimez jamais le code crontab, utilisez plutôt le serveur de messagerie et vérifiez le courrier de l'utilisateur. Cela donne un aperçu plus clair de ce qui se passe.


Une autre raison pour laquelle crontab échouera :traitement spécial du % caractère.

À partir du fichier manuel :

The entire command portion of the line, up to a newline or a
"%" character, will be executed by /bin/sh or by the shell specified
in the SHELL variable of the cronfile.  A "%" character in the
command, unless escaped with a backslash (\), will be changed into
newline characters, and all data after the first % will be sent to
the command as standard input.

Dans mon cas particulier, j'utilisais date --date="7 days ago" "+%Y-%m-%d" pour produire des paramètres pour mon script, et il échouait silencieusement. J'ai finalement découvert ce qui se passait quand j'ai vérifié syslog et j'ai vu que ma commande était tronquée au % symbole. Vous devez y échapper comme ceci :

date --date="7 days ago" "+\%Y-\%m-\%d"

Voir ici pour plus de détails :

http://www.ducea.com/2008/11/12/using-the-character-in-crontab-entries/


Linux
  1. Configuration de la tâche Godaddy cron pour exécuter le script php

  2. Exécution d'une tâche cron sous Linux toutes les six heures

  3. Commande Linux pour vérifier si un script shell est en cours d'exécution ou non

  4. Comment afficher une tâche cron en cours d'exécution ?

  5. la tâche cron ne s'exécute parfois pas

Comment utiliser cron sous Linux

.bash_profile n'est pas fourni lors de l'exécution de Su ?

Cron Job pour vérifier si le script Php est en cours d'exécution, sinon, exécutez-le ?

Vim ne fonctionne pas dans Tmux ?

Apache/Mysql ne fonctionne pas. Mauvais?

Pourquoi ma tâche cron ne m'envoie-t-elle pas d'e-mail ?