Comment lire une expression cron
Une expression cron est faite de cinq valeurs séparées par des espaces, lues de gauche à droite comme minute, heure, jour du mois, mois, jour de la semaine. La tâche s'exécute quand l'heure courante correspond à chacun des champs.
30 4 * * 1
│ │ │ │ │
│ │ │ │ └── day of week (1 = Monday)
│ │ │ └──── month (any)
│ │ └────── day of month (any)
│ └──────── hour (4am)
└─────────── minute (30)
Celle-ci se lit « à 04:30 tous les lundis ».
Les cinq champs
| # | Champ | Valeurs autorisées | Remarques |
|---|---|---|---|
| 1 | Minute | 0 à 59 | |
| 2 | Heure | 0 à 23 | Horloge de 24 heures, 0 est minuit |
| 3 | Jour du mois | 1 à 31 | |
| 4 | Mois | 1 à 12, ou JAN à DEC | |
| 5 | Jour de la semaine | 0 à 6, ou SUN à SAT | 0 est dimanche, et la plupart des implémentations de cron acceptent aussi 7 |
Certains ordonnanceurs emploient une autre forme. Quartz, utilisé par beaucoup de logiciels Java, place les secondes en premier, ajoute une année facultative, et numérote ses jours de la semaine de 1 à 7 en commençant par dimanche. Si une expression compte six ou sept champs, vérifiez pour quel système elle a été écrite avant de vous fier à votre lecture.
Les opérateurs
Il y en a quatre, et ils se combinent au sein d'un même champ.
| Symbole | Nom | Exemple | Signification |
|---|---|---|---|
* | N'importe lequel | * * * * * | Chaque minute de chaque jour |
, | Liste | 0 9,13,17 * * * | À 09:00, 13:00 et 17:00 |
- | Plage | 0 9-17 * * * | Toutes les heures de 09:00 à 17:00 inclus |
/ | Pas | */15 * * * * | À :00, :15, :30 et :45 |
Un pas s'applique toujours à une plage. */15 dans le champ des minutes signifie « en partant de 0, prendre une valeur sur 15 jusqu'à 59 ». Vous pouvez aussi appliquer un pas à une plage explicite : 5-30/10 donne 5, 15 et 25, puis s'arrête parce que 35 dépasse la fin.
Un pas ne signifie pas « toutes les 15 minutes à partir de maintenant » ; il sélectionne des valeurs fixes sur l'horloge. */40 se déclenche à :00 et à :40, puis n'attend que 20 minutes jusqu'au :00 de l'heure suivante, car le comptage repart à chaque heure. Une liste peut contenir des plages et des pas, si bien que 0 0-6/2,12,18-23 * * * est un champ d'heures valide.
Noms et raccourcis
Les champs du mois et du jour de la semaine acceptent des noms de trois lettres, et la casse n'a pas d'importance : JAN, jan et Jan sont identiques. La documentation classique de crontab indique que les plages et les listes de noms ne sont pas autorisées, même si beaucoup d'implémentations modernes acceptent bel et bien MON-FRI. Si vous ne savez pas avec certitude ce qui exécute votre tâche, utilisez des nombres : 1-5 est sans ambiguïté partout.
Plusieurs raccourcis remplacent l'expression complète à cinq champs :
| Raccourci | Équivalent | S'exécute |
|---|---|---|
@yearly ou @annually | 0 0 1 1 * | À minuit, le 1er janvier |
@monthly | 0 0 1 * * | À minuit, le 1er du mois |
@weekly | 0 0 * * 0 | À minuit le dimanche |
@daily ou @midnight | 0 0 * * * | À minuit chaque jour |
@hourly | 0 * * * * | À l'heure pile |
@reboot existe aussi, mais ce n'est pas une planification : il exécute la tâche une seule fois, au démarrage de cron lui-même.
Le piège du jour du mois et du jour de la semaine
C'est celui qui mord. Quand le champ du jour du mois et celui du jour de la semaine sont tous deux restreints, c'est-à-dire qu'aucun n'est *, cron exécute la tâche quand l'un ou l'autre correspond, et non quand les deux correspondent.
0 0 13 * 5
Vous pourriez lire cela comme « minuit le vendredi 13 ». Cela signifie en réalité « minuit le 13 de chaque mois, et aussi minuit chaque vendredi » : plus de soixante exécutions par an au lieu d'une ou deux.
Le comportement ET auquel vous vous attendiez ne s'applique que si l'un des deux champs est *. Ainsi 0 0 * * 5 désigne chaque vendredi et 0 0 13 * * chaque 13 du mois, deux cas parfaitement normaux. C'est le fait de contraindre les deux qui déclenche le OU.
Il n'existe pas de façon standard d'exprimer « le vendredi 13 » en cinq champs. La solution de contournement habituelle consiste à planifier chaque 13 du mois et à faire vérifier le jour de la semaine par la tâche avant tout travail.
Une subtilité voisine : certaines implémentations déterminent si un champ est restreint en vérifiant s'il commence littéralement par *. Sous celles-là, 0-6 dans le champ du jour de la semaine compte comme restreint alors même qu'il couvre tous les jours, ce qui active discrètement le comportement OU. Employez * quand vous voulez dire « n'importe lequel ».
Des erreurs qui valent la peine d'être vérifiées
* */2 * * *s'exécute chaque minute pendant une heure sur deux, soit 720 exécutions par jour. Vous vouliez0 */2 * * *, qui en fait 12.- Un champ de minutes manquant décale tout d'un cran vers la gauche et s'analyse en général quand même, ce qui vous donne une planification valide à un moment complètement faux.
0 0 31 * *saute silencieusement les mois qui n'ont pas de 31.- Cron utilise le fuseau horaire du système ou de l'utilisateur, à moins que l'ordonnanceur ne vous laisse en fixer un. Quand les horloges basculent pour l'heure d'été, une tâche placée dans l'heure sautée peut ne pas s'exécuter du tout, et une tâche placée dans l'heure répétée peut s'exécuter deux fois, selon l'implémentation. Les tâches qui doivent s'exécuter une fois par jour sont plus sûres si on les planifie loin des petites heures où le basculement se produit.
Dans le doute, relisez l'expression comme une phrase, puis vérifiez les prochains moments auxquels elle se déclencherait réellement. Si ces dates ne correspondent pas à ce que vous avez décrit, c'est l'expression qui est fausse, pas votre lecture.