Une expression cron est une ligne de cinq champs séparés par des espaces qui décrit quand une tâche doit s’exécuter : minute, heure, jour du mois, mois et jour de la semaine. 0 9 * * 1-5 signifie « à 9 h 00 du lundi au vendredi ». La même syntaxe est utilisée par le crontab de Linux et macOS, par GitHub Actions, par Kubernetes et par la plupart des planificateurs, avec de petites différences qu’il vaut mieux connaître.
Cet article explique chaque champ, les quatre caractères spéciaux, les cas qui déroutent le plus (le dimanche en 0 ou 7, la combinaison jour du mois et jour de la semaine, les fuseaux horaires) et rassemble des exemples à copier.
Les cinq champs
┌───────────── minute (0-59)
│ ┌───────────── heure (0-23)
│ │ ┌───────────── jour du mois (1-31)
│ │ │ ┌───────────── mois (1-12 ou jan-dec)
│ │ │ │ ┌───────────── jour de la semaine (0-6, dimanche = 0 ; souvent aussi 7 = dimanche, et mon-sun)
│ │ │ │ │
* * * * * commande
L’ordre ne change jamais. Les noms abrégés en anglais (jan, mon) sont acceptés par la plupart des implémentations, mais les chiffres fonctionnent partout : c’est le choix sûr.
Les quatre caractères spéciaux
| Caractère | Signification | Exemple |
|---|---|---|
* |
N’importe quelle valeur | * * * * * chaque minute |
, |
Liste de valeurs | 0 9,18 * * * à 9 h 00 et à 18 h 00 |
- |
Intervalle | 0 9 * * 1-5 à 9 h 00 du lundi au vendredi |
/ |
Pas | */15 * * * * toutes les 15 minutes (0, 15, 30, 45) |
Ils se combinent : 0 8-20/2 * * 1-5 s’exécute toutes les deux heures entre 8 h 00 et 20 h 00 les jours ouvrés. Un détail sur le pas : */15 dans le champ des minutes commence à 0 ; 5/15 (valide dans certaines implémentations, pas en POSIX) commencerait à la minute 5.
Exemples prêts à copier
| Expression | Quand elle s’exécute |
|---|---|
*/5 * * * * |
Toutes les 5 minutes |
0 * * * * |
Toutes les heures, à l’heure pile |
30 2 * * * |
Tous les jours à 2 h 30 |
0 9 * * 1-5 |
Du lundi au vendredi à 9 h 00 |
0 10 * * 6,0 |
Samedi et dimanche à 10 h 00 |
0 0 1 * * |
Le 1er de chaque mois à minuit |
0 0 1 1 * |
Le 1er janvier à minuit |
0 6 * * 1 |
Le lundi à 6 h 00 |
0 */6 * * * |
Toutes les 6 heures (0 h, 6 h, 12 h, 18 h) |
15 14 1 * * |
Le 1er de chaque mois à 14 h 15 |
Pour vérifier une expression avant de la mettre en production, l’outil d’expressions cron d’AIMRAN Tools la traduit en langage naturel et affiche les prochaines exécutions, ce qui évite la surprise classique de découvrir l’erreur quand la tâche ne s’est déjà pas exécutée.
Les trois points qui déroutent le plus
1. Jour du mois et jour de la semaine se combinent par « ou »
D’après crontab(5), si les deux champs ont une valeur autre que *, la tâche s’exécute quand l’un ou l’autre correspond. 0 9 13 * 5 ne signifie pas « le vendredi 13 », mais « tous les 13 à 9 h 00 et aussi tous les vendredis à 9 h 00 ». Pour « le vendredi 13 », il faut vérifier le jour de la semaine dans la commande elle-même.
2. Le dimanche vaut 0 (et généralement aussi 7)
La norme POSIX définit le dimanche comme 0. Vixie cron (le plus courant sous Linux) accepte aussi 7. D’autres planificateurs non : utilisez 0 pour rester portable.
3. Le fuseau horaire n’est pas dans l’expression
Une expression cron ne porte pas de fuseau horaire : elle est interprétée dans celui du système qui l’exécute. Dans GitHub Actions, c’est toujours UTC : 0 9 * * 1-5 s’exécute à 9 h 00 UTC (11 h 00 en France en été). Dans Kubernetes, vous pouvez ajouter timeZone: "Europe/Paris" à la spécification du CronJob. Sur un serveur Linux, cela dépend de la configuration du système ou de la variable CRON_TZ si le cron la prend en charge.
Différences entre environnements
| Environnement | Particularités |
|---|---|
Linux / macOS (crontab -e) |
Cinq champs. Vixie cron accepte des raccourcis comme @daily, @hourly, @weekly, @monthly, @reboot. La sortie est envoyée par courrier local si elle n’est pas redirigée. |
GitHub Actions (on: schedule) |
Cinq champs entre guillemets, UTC, intervalle minimal de 5 minutes. Les exécutions peuvent être retardées en période de forte charge et le planificateur se désactive dans les dépôts sans activité pendant 60 jours. |
Kubernetes (CronJob) |
Cinq champs, prend en charge timeZone, les raccourcis @hourly, etc., et les politiques de concurrence (concurrencyPolicy). |
| Certains outils (Quartz, Spring, certains services cloud) | Ajoutent un sixième champ de secondes au début ou un septième pour l’année. Y coller une expression à cinq champs la décale et change complètement son sens. |
Bonnes pratiques
- Vérifiez l’expression avec un outil qui affiche les prochaines exécutions avant de l’enregistrer.
- Documentez l’intention dans un commentaire au-dessus (
# sauvegarde quotidienne 2 h 30), car l’expression seule ne se lit pas d’un coup d’œil. - Évitez les heures pile si ce n’est pas nécessaire : beaucoup de tâches se concentrent à
0 0 * * *et0 * * * *; décaler de quelques minutes répartit la charge (c’est ce que font les planificateurs cloud eux-mêmes). - Redirigez la sortie (
>> /var/log/tache.log 2>&1) pour que cron n’accumule pas de courriers et que vous puissiez déboguer. - Rendez la tâche idempotente : si cron la lance deux fois ou qu’elle chevauche la précédente, rien ne doit casser. Un verrou (
flock -n) évite les chevauchements.
Conclusion
Cinq champs, quatre symboles et trois pièges : le « ou » entre jour du mois et jour de la semaine, le dimanche en 0 et le fuseau horaire du système. Avec cela, vous couvrez presque toute planification. Et avant de faire confiance à une expression, vérifiez-la : deux minutes avec un vérificateur évitent une tâche qui ne s’est pas exécutée à 2 h 30 du matin.