cron · planification · unix
Qu'est-ce que cron, exactement ?
Une entrée cron, ce sont cinq champs de temps et une commande. Dans l'ordre : minute, heure, jour du mois, mois, jour de la semaine.
30 4 * * 1 /usr/local/bin/backup.sh Cela se lit : minute 30, heure 4, n'importe quel jour du mois, n'importe quel mois, jour de la semaine 1. Quatre heures et demie du matin, le lundi.
Le vocabulaire d'un champ
Chaque champ accepte plus qu'un simple nombre. * signifie toutes les valeurs. 1-5 est un intervalle. 1,15 est une liste. */15 est un pas - une valeur sur quinze, soit quatre fois par heure dans le champ des minutes.
Deux champs acceptent aussi des noms : les mois de JAN à DEC, les jours de la semaine de SUN à SAT. Et le champ jour de la semaine a une bizarrerie connue : 0 et 7 désignent tous deux le dimanche dans la plupart des implémentations.
Le champ qui est un OU
Voici la partie qui surprend, et elle mérite une seconde lecture.
Le jour du mois et le jour de la semaine sont deux façons différentes de désigner le même jour. Quand vous n'en remplissez qu'un et laissez l'autre à *, cron se comporte exactement comme prévu. Quand vous remplissez les deux, POSIX spécifie qu'un jour correspondant à l'un ou l'autre champ déclenche la tâche.
C'est un OU, pas un ET.
Ainsi 0 0 1 * 1 ne veut pas dire « le premier du mois, s'il tombe un lundi ». Cela veut dire le premier de chaque mois, et tous les lundis - soit environ cinq fois plus d'exécutions que prévu.
Le raisonnement derrière ce choix se défend. Un ET ferait que la plupart des combinaisons ne se déclencheraient presque jamais : « le 31 quand c'est un vendredi » arrive une ou deux fois par an. Le OU permet à une seule ligne d'exprimer « mensuel et hebdomadaire » sans seconde entrée. Mais c'est l'inverse de ce que la syntaxe laisse croire, et c'est là que des tâches planifiées s'exécutent discrètement les mauvais jours.
Les raccourcis, et pourquoi ils ne sont pas portables
Beaucoup d'implémentations acceptent @daily, @hourly, @weekly, @monthly et @reboot. Ils sont pratiques et ils ne font pas partie de POSIX : ils viennent de Vixie cron et de ses descendants.
Sur une machine que vous maîtrisez, cela n'a pas d'importance. Dans quelque chose qui doit tourner n'importe où - une image de conteneur, un script que vous distribuez - les cinq champs explicites sont le choix sûr. @reboot en particulier n'a aucun équivalent dans le standard, et son comportement dépend entièrement de l'implémentation.
Ce que cron ne fait pas
Il ne rattrape pas. Si la machine était éteinte à 4h30, la tâche de 4h30 n'a pas tourné et ne sera pas relancée. Cron se déclenche sur une correspondance d'horloge, il ne tient pas de file d'attente du travail manqué.
Il ne vous donne pas votre environnement de connexion. Une tâche cron s'exécute avec un PATH minimal et rien de votre profil shell. Le « ça marche dans mon terminal mais pas dans cron » le plus fréquent est une commande trouvée via un PATH que cron n'a pas. Utilisez des chemins absolus.
Il n'empêche pas le chevauchement. Si une tâche planifiée toutes les cinq minutes en prend six, vous obtenez deux copies simultanées. Cron lancera la suivante quoi qu'il arrive ; le fichier de verrou est votre affaire, pas la sienne.
Il ne vous dit pas qu'il a échoué. La sortie part par courriel si le courriel est configuré, et dans le néant sinon. Redirigez vers un fichier de journal et consultez-le, ou vous l'apprendrez par la sauvegarde manquante.
Lisez l'expression avant de lui faire confiance
Parce que le OU est invisible dans la syntaxe, une expression qui a l'air juste peut être fausse d'une manière qui ne se manifeste que des semaines plus tard. La décoder champ par champ avant de déployer coûte quelques secondes - c'est à cela que sert le décodeur d'expression cron de ce site.
Un calendrier avec les noms des jours sur le côté et les numéros de jours dans la grille. Cron a un champ pour chacun, et quand vous remplissez les deux, il retient l'un OU l'autre - pas les deux ensemble.