Souvent, les crontab
scripts ne sont pas exécutés comme prévu ou comme prévu. Il y a de nombreuses raisons à cela:
- mauvaise notation crontab
- problème d'autorisations
- Variables d'environnement
Ce wiki de communauté vise à regrouper les principales raisons pour lesquelles les crontab
scripts 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.
crontab -e
pour que le cron prenne effet. Par exemple, avec vim, je modifie le fichier et l’utilise:w
pour 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:q
aussi.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:
Attendez
/tmp/env.output
d’être créé, puis supprimez à nouveau le travail. Maintenant, comparez le contenu de/tmp/env.output
avec la sortie deenv
run dans votre terminal habituel.Un "gotcha" commun ici est que la
PATH
variable d'environnement est différente. Peut-être votre script cron utilise la commandesomecommand
trouvée dans/opt/someApp/bin
, que vous avez ajouté àPATH
en/etc/environment
? cron ignorePATH
ce fichier, donc l'exécutionsomecommand
de 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/environment
seront transmises aux tâches cron, mais pas les variables que cron se définit spécifiquement, telles quePATH
.Pour contourner ce problème, définissez simplement votre propre
PATH
variable en haut du script. Par exempleCertains 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/bin
place. Vous devrez parcourir tout le script en remplaçant/opt/someApp/bin
par/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
la source
env
j'avais complètement oublié cette commande et je pensais que PATH fonctionnait. En fait, c'était tout à fait différent dans mon cas.Mon haut le casse-tête: 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 appropriée dans les pages de manuel de ce problème (
man crontab
passez à la fin):la source
man crontab
sur 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.)crontab -e
il vérifiera la syntaxe du fichier avant de permettre une sauvegarde, y compris une vérification de la nouvelle ligne.-e
option. Il est indépendant de l'éditeur.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:
Si vous ne voyez aucun numéro, cron ne fonctionne pas.
sudo /etc/init.d/cron start
peut ê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
EDIT: Vous pouvez aussi utiliser systemctl dans Linux moderne, par exemple
la source
pidof cron
qui omettra les résultats d'autres applications comportant également le mot "cron", comme crontab.sudo service cron start
je reçoisstart: Job is already running: cron
service crond start
si ses centos / RHELLe 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):
Donc, si vous avez un script cron
backup.sh
,analyze-logs.pl
dans lecron.daily/
répertoire, vous feriez mieux de supprimer les noms d'extension.la source
run-parts --test
(ou une autre option imaginaire, telle--debug
que la sortie des fichiers qu’elle saute, y compris le motif).Dans de nombreux environnements, cron exécute les commandes en utilisant
sh
, alors que de nombreuses personnes supposent qu'il l'utiliserabash
.Suggestions pour tester ou résoudre ce problème pour une commande qui échoue:
Essayez d’exécuter la commande
sh
pour voir si cela fonctionne:Emballez la commande dans un sous-shell bash pour vous assurer qu’elle est exécutée dans bash:
Dites à cron d'exécuter toutes les commandes dans bash en plaçant le shell en haut de votre crontab:
Si la commande est un script, assurez-vous qu'il contient un shebang:
la source
bash
, mais pas aveccron
. Merci!source
est en bash mais pas sh. Dans cron / sh, utilisez un point:. envfile
plutôt quesource envfile
.sh "mycommand"
indiquesh
d'exécuter mycommand en tant que fichier de script. Vouliez-vous diresh -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 poursh
ici?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:
la source
* * * * * touch /tmp/cronworks
ne rien faire, pourtant, il estRELOAD
à cronlog.Le chemin absolu doit être utilisé pour les scripts:
Par exemple,
/bin/grep
devrait être utilisé à la place degrep
:Au lieu de:
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
cron
n'a pas la mêmePATH
variable d'environnement que l'utilisateur.la source
/usr/bin/whatever
chemin completSi 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
la source
date
intérieur d'un travail cron tab?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.la source
cron
, et facilement traçable en essayant simplement d'exécuter à/path/to/script
partir de la ligne de commande.. scriptname
oush scriptname
oubash scriptname
, cela devient uncron
problème spécifique.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.log
et 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:
devrait être édité (
sudo nano /etc/rsyslog.conf
) non commenté à:Après cela, vous devez redémarrer rsyslog via
ou
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
pour afficher les messages liés à cron.
la source
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=:0
quelque part.la source
* * * * * export DISPLAY=:0 && <command>
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é.
la source
Permission non sécurisée sur la table cron
Une table cron est rejetée si son autorisation n'est pas sécurisée
Le problème est résolu avec
la source
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
cd
devra 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
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
:la source
chdir(dirname(__FILE__));
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/crontab
et 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 found
lors de/etc/crontab
déclarations telles que le déplacement d'une commande ou d'un fichier dans/etc/cron.d
le fichier crontab d'un utilisateur.Inversement, cron générera des erreurs similaires
/usr/bin/restartxyz is not a valid username
ou similaires lorsque l'inverse se produit.la source
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:
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':
la source
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 *
ou11 15 * * *
. Le jour de la semaine pour les travaux après minuit est également confus. MF est2-6
après minuit, non1-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/3
spé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 comme1-5
ou1,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/bin
utilisé 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 -l
si 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: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.
la source
30 23 * * *
traduit à 23h15?15 23 * * *
. Corrigé maintenant.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:
Tout ce que vous devez faire est de courir:
en tant que root pour déverrouiller le compte, et la crontab devrait fonctionner à nouveau.
la source
Si vous avez une commande comme celle-ci:
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:
pour voir si cela vous aide à résoudre votre problème.
la source
=== 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 -f
avec 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
la source
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
cron
travail quotidien pour s’exécuter à une heure arbitraire, lorsque la charge de la base de données était faible.J'ai créé un fichier
mycronjob
avec le programme cron, le nom d'utilisateur et la commande et l' ai copié dans le/etc/cron.d
répertoire. Mes deux pièges:mycronjob
le fichier devait appartenir à root pour être exécutéUn problème d'autorisation apparaîtra
/var/log/syslog
comme quelque chose de similaire à:La première ligne fait référence à
/etc/crontab
fichier et la dernière à un fichier que j'ai placé sous/etc/cront.d
.la source
La ligne écrite d'une manière que crontab ne comprend pas. Il doit être correctement écrit. Voici CrontabHowTo .
la source
Le démon Cron peut être en cours d'exécution, mais ne fonctionne pas réellement. Essayez de redémarrer cron:
la source
pidof
cron et je n'ai rien eu. Essayé d'utiliser l'service
utilitaire et il a été dit que cron fonctionnait déjà. Il suffit d'exécuter cette commande et de l'exécuter àpidof
nouveau et j'obtiens un résultat.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:
alors que / etc / crontab serait:
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 passagecrontab -e
). .Par exemple, j'ai vu des exemples de personnes ayant l'
sudo crontab -e
habitude d'exécuter un script avec des autorisations root, avec une correspondancechown username file_output
dans le script shell. Sloppy, mais ça marche. IMHO, l'option la plus gracieuse est de le mettre/etc/crontab
avec le nom d'utilisateur déclaré et les autorisations appropriées, pourfile_output
aller au bon endroit et au bon propriétaire.la source
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.
la source
/dev/null
. Par exemple:some-command > /dev/null
Ceci 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, utilisezsome-command &> /dev/null
.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:
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:
la source
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
goaccess
d'analyse des fichiers journaux du serveur Web. Cela ne marche PAS dans cron:et
goaccess
affiche la page d'aide au lieu de créer le rapport. Dans la coque, ceci peut être reproduit avecLe correctif
goaccess
est 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 enla source
Dans mon cas, cron et crontab avaient des propriétaires différents.
Je ne travaillais pas, j'avais ceci:
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:
la source
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.
la source
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:
la source