Comment construire des expressions cron
Les expressions cron sont la manière standard de définir des planifications récurrentes sous Linux, sur les plateformes cloud, dans les pipelines CI/CD et les ordonnanceurs de tâches. La syntaxe est compacte mais peu intuitive : construire un générateur cron visuel vous montre exactement quand votre tâche s'exécutera, attrape les erreurs courantes avant le déploiement et supprime les devinettes de la partie la plus sujette aux erreurs de l'automatisation. Une fois que vous comprenez les cinq champs, les caractères spéciaux et les pièges les plus courants, vous pouvez spécifier n'importe quelle planification récurrente avec confiance.
Une brève histoire de cron
Le premier cron est venu de Brian Kernighan dans la version 7 d'Unix, vers 1979. Il relisait sa configuration chaque minute et exécutait tout ce qui était dû. Paul Vixie l'a réécrit en 1987 en ce qu'on appelle aujourd'hui Vixie cron, qui est la version que la plupart des distributions Linux livrent encore. Vixie cron a ajouté les crontabs par utilisateur, les variables d'environnement, le mot-clé @reboot et plusieurs fonctionnalités de confort qui ont rendu le format utilisable par les non-administrateurs.
La syntaxe à 5 champs a à peine changé en plus de quarante ans. Amazon EventBridge, Google Cloud Scheduler, Kubernetes CronJob, GitHub Actions, GitLab CI, Jenkins, Airflow, n8n et des dizaines d'autres systèmes consomment tous le même format compact avec seulement des extensions mineures. Cette stabilité est la raison pour laquelle cron vaut la peine d'être appris une fois et jamais réappris. La compétence se transfère partout où l'automatisation tourne sur une horloge.
Syntaxe cron
Une expression cron standard a 5 champs, séparés par des espaces. Chaque champ contrôle une tranche de temps, et une tâche s'exécute chaque fois que tous les champs correspondent au moment actuel.
┌───────────── minute (0-59)
│ ┌───────────── heure (0-23)
│ │ ┌───────────── jour du mois (1-31)
│ │ │ ┌───────────── mois (1-12, ou JAN-DEC)
│ │ │ │ ┌───────────── jour de la semaine (0-6, Dim=0, ou SUN-SAT)
│ │ │ │ │
* * * * *
Les champs sont combinés avec ET pour l'heure, la minute et le mois, mais jour-du-mois et jour-de-la-semaine sont combinés avec OU dans Vixie cron. Cela signifie que 0 12 1 * 1 se déclenche le 1er de chaque mois ET chaque lundi à midi, pas uniquement les lundis qui tombent le 1er. Ce piège attrape presque tout le monde la première fois.
Planifications cron courantes
Les schémas que vous utiliserez le plus souvent :
| Planification | Expression | Signification |
|---|---|---|
| Chaque minute | * * * * * | S'exécute toutes les 60 secondes |
| Toutes les 5 minutes | */5 * * * * | À :00, :05, :10, :15... |
| Toutes les 15 minutes | */15 * * * * | À :00, :15, :30, :45 |
| Chaque heure | 0 * * * * | Au sommet de chaque heure |
| Toutes les 2 heures | 0 */2 * * * | À 00:00, 02:00, 04:00... |
| Quotidien à minuit | 0 0 * * * | Une fois par jour à 00:00 |
| Quotidien à 9h | 0 9 * * * | Une fois par jour à 09:00 |
| Deux fois par jour | 0 9,21 * * * | À 09:00 et 21:00 |
| Tous les lundis à 8h | 0 8 * * 1 | Hebdomadaire le lundi |
| En semaine à 18h | 0 18 * * 1-5 | Du lundi au vendredi |
| 1er de chaque mois | 0 0 1 * * | Mensuel à minuit le 1er |
| Chaque trimestre | 0 0 1 */3 * | 1er jan, 1er avr, 1er juil, 1er oct |
| Chaque matin en semaine | 0 7 * * 1-5 | 07:00 du lundi au vendredi |
| Dimanche à midi | 0 12 * * 0 | Hebdomadaire le dimanche |
Beaucoup de systèmes acceptent aussi des alias abrégés qui s'étendent à l'expression à 5 champs équivalente : @yearly, @monthly, @weekly, @daily, @hourly et @reboot. Ils sont concis mais non universels, vérifiez donc votre plateforme avant de vous y fier.
Comment construire une expression cron
- Choisissez la granularité : avez-vous besoin de chaque minute, chaque heure, une fois par jour, une fois par semaine ou une fois par mois ? Commencez au réglage le plus grossier qui répond à votre besoin.
- Utilisez les contrôles visuels : sélectionnez les valeurs de minute, heure, jour, mois et jour de la semaine dans les listes déroulantes. Ou commencez avec un préréglage comme "chaque heure" ou "quotidien à minuit" et ajustez.
- Prévisualisez les prochaines exécutions : le générateur affiche les 5 prochains horaires d'exécution, ce qui vous permet de confirmer que la planification se déclenche quand vous l'attendez.
- Vérifiez le fuseau horaire : la prévisualisation doit correspondre au fuseau horaire du serveur ou de l'ordonnanceur qui exécutera la tâche, pas à votre heure locale.
- Copiez l'expression et collez-la dans votre crontab, votre YAML GitHub Actions, votre règle AWS EventBridge ou tout autre ordonnanceur que vous utilisez.
- Testez d'abord avec un intervalle court avant de valider la planification finale. Un rapide
*/5 * * * *prouve que la tâche se déclenche ; une fois que vous voyez deux ou trois exécutions, remplacez par l'expression réelle.
Caractères et opérateurs spéciaux
Cron prend en charge un petit mais puissant ensemble d'opérateurs à l'intérieur de n'importe quel champ.
| Caractère | Signification | Exemple |
|---|---|---|
* | Toute valeur | * * * * * = chaque minute |
*/n | Tous les n | */15 * * * * = toutes les 15 min |
, | Plusieurs valeurs discrètes | 0 8,12,18 * * * = 8h, midi, 18h |
- | Plage inclusive | 0 9-17 * * * = chaque heure de 9h à 17h |
n-m/k | Plage avec pas | 0 9-17/2 * * * = 9, 11, 13, 15, 17 |
? | Pas de valeur spécifique (Quartz uniquement) | 0 0 ? * MON (ordonnanceurs Java) |
L | Dernier (AWS, Quartz) | L dans DoM = dernier jour du mois |
W | Jour ouvré le plus proche (AWS, Quartz) | 15W = jour ouvré le plus proche du 15 |
# | Nième jour de la semaine (AWS, Quartz) | MON#2 = deuxième lundi du mois |
@hourly | Raccourci | Identique à 0 * * * * |
Vixie cron classique ne prend en charge que les cinq premières lignes. Les opérateurs avancés (L, W, #, ?) viennent de Quartz, la bibliothèque de planification Java, et ont été adoptés par AWS EventBridge et quelques autres ordonnanceurs cloud. Ils ne sont pas portables, ne les mélangez donc pas avec du code qui doit tourner sur un Linux générique.
Cron sur différentes plateformes
Cron est une famille de syntaxes apparentées, pas un standard unique. Savoir quel dialecte parle votre ordonnanceur fait gagner des heures de débogage.
| Plateforme | Champs | Notes |
|---|---|---|
| Vixie cron (Linux) | 5 | Le classique. */n, plages, listes, pas d'opérateurs avancés |
| BSD cron | 5 | Comme Vixie mais légères différences d'environnement |
| crontab.guru | 5 | Analyseur web qui reflète la sémantique Vixie |
| GitHub Actions | 5 | Syntaxe Vixie, tourne en UTC, résolution minimale 5 minutes |
| GitLab CI | 5 | Syntaxe Vixie, tourne dans le fuseau de l'instance |
| AWS EventBridge | 6 | Ajoute l'année. Jour de la semaine utilise 1-7 (Dim=1), supporte L/W/# |
| Google Cloud Scheduler | 5 | Syntaxe Vixie plus configuration de fuseau horaire |
| Kubernetes CronJob | 5 | Syntaxe Vixie avec raccourcis @ |
| Quartz (Java) | 6 ou 7 | Ajoute les secondes au début et l'année optionnelle |
| Timers systemd | Format OnCalendar | Pas cron, mais résout le même problème avec une syntaxe plus claire |
Si vous écrivez une planification qui doit tourner sur plus d'une plateforme, tenez-vous au sous-ensemble conservateur à 5 champs que tout système comprend. N'utilisez L, W ou # que lorsque vous savez que la destination les prend en charge.
Pièges courants
- Jour-du-mois et jour-de-la-semaine sont combinés avec OU, une expression comme
0 9 15 * 1se déclenche chaque lundi ET le 15 de chaque mois, pas uniquement le 15 quand il tombe un lundi. Pour intersecter, vous avez généralement besoin d'un wrapper externe ou d'un autre ordonnanceur. - Confusion de fuseau horaire, les crontabs serveur tournent presque toujours en UTC. Si vous voulez 9h heure de l'Est, c'est
0 14 * * *UTC en hiver mais0 13 * * *UTC en été à cause de l'heure d'été. Utilisez un ordonnanceur qui supporte les indications de fuseau, ou normalisez tout en UTC. - Transitions d'heure d'été, les tâches planifiées à 02:30 heure locale peuvent s'exécuter deux fois quand on recule l'heure et pas du tout quand on l'avance. Planifiez les tâches sensibles en dehors de la fenêtre 01:00-03:00 ou utilisez UTC.
- Le piège
MAILTOde Vixie, si votre tâche imprime quoi que ce soit sur stdout, Vixie cron envoie la sortie par email à l'utilisateur propriétaire de la crontab. Sur les serveurs sans relais mail, cela remplit vite/var/spool/mail. Redirigez la sortie vers un fichier journal avec>>/var/log/myjob.log 2>&1. - L'environnement n'est pas votre shell de connexion, cron tourne avec un environnement dépouillé : pas de
PATHdepuis votre.bashrc, pas de virtualenv, pas denvm. Définissez les variables dont vous avez besoin en haut de la crontab ou appelez votre script avec un chemin absolu. - Les pourcentages doivent être échappés, un
%non échappé dans une crontab Vixie est interprété comme un caractère de nouvelle ligne dans la commande. Échappez-le toujours en\%si votre commande a besoin d'un signe pourcent littéral, par exemple dans un appeldate +"%Y-%m-%d". - Les tâches longues se chevauchent, cron ne saute pas une exécution parce que la précédente est encore en cours. Si votre tâche peut dépasser l'intervalle, enveloppez-la dans un fichier de verrou (
flock,setlock) ou utilisez un exécuteur qui gère la concurrence. - Débordement à 59 minutes,
*/40 * * * *ne se déclenche pas toutes les 40 minutes. Il se déclenche à la minute 0 et 40 de chaque heure parce que les valeurs de pas bouclent autour des limites du champ. Pour de véritables intervalles de 40 minutes, vous avez besoin d'un ordonnanceur plus riche. - Oublier
0dans le champ minute,* 9 * * *tourne chaque minute de 09:00 à 09:59, pas une fois à 09:00. Le champ minute a besoin d'une valeur explicite si vous voulez un seul déclenchement par heure. - Cron n'est pas fiable sur les portables, anacron existe pour cette raison. Vixie cron ne rattrape pas les exécutions manquées après une mise en veille, donc une sauvegarde quotidienne planifiée à 03:00 ne tournera pas si le portable était fermé à cette heure. Utilisez anacron, des timers systemd avec
Persistent=true, ou un plist launchd sur macOS.
Alternatives à cron
Pour certaines charges de travail, la résolution grossière à la minute de cron et son absence de comptabilité commencent à faire mal. Les améliorations les plus courantes :
| Outil | Force | Quand le choisir |
|---|---|---|
| Timers systemd | Syntaxe OnCalendar claire, persistant à travers les redémarrages, s'intègre aux units | Vous utilisez déjà systemd et voulez un logging plus riche |
| Anacron | Rattrape les exécutions manquées après une veille | Portables ou machines qui ne sont pas toujours allumées |
| Airflow / Dagster | Dépendances DAG, retries, observabilité | Pipelines de données multi-étapes |
| Temporal | Flux d'état, garanties exactement-une-fois | Orchestration longue durée entre services |
| AWS EventBridge | Géré, intègre Lambda, S3, SQS | Tout ce qui est cloud-natif sur AWS |
| GitHub Actions | Gratuit pour les dépôts publics, tourne sur des runners hébergés | Tâches planifiées adjacentes au CI |
| fonctions serverless sur déclencheurs cron | Pas de serveur à maintenir | Tâches légères qui tiennent dans un Lambda |
Cron reste la bonne réponse pour la grande majorité des tâches récurrentes ponctuelles. Les autres outils brillent quand vous avez besoin d'état, de retries, de dépendances ou de coordination entre machines.
Vie privée et le générateur cron
Le générateur d'expressions cron tourne entièrement dans votre navigateur. La planification que vous construisez, la prévisualisation des prochaines exécutions et l'expression copiée ne touchent jamais nos serveurs. Il n'y a aucun journal des expressions générées, aucune télémétrie sur les préréglages populaires, et aucun moyen pour quiconque de reconstruire la planification sur laquelle vous travailliez. Les expressions cron ne sont pas des données personnelles à première vue, mais la planification d'une tâche (un export de base de données nocturne, une exécution de facturation hebdomadaire, une synchronisation horaire vers un partenaire) peut révéler beaucoup sur le fonctionnement d'une entreprise. Garder cette information côté client évite de divulguer accidentellement des schémas d'infrastructure à un tiers. Pour une tâche aussi routinière que choisir une planification, le réglage par défaut de vie privée devrait correspondre à la sensibilité de ce que ces planifications représentent.
Questions fréquentes
Quel est le format d'une expression cron ?
Une expression cron standard a 5 champs séparés par des espaces, représentant minute (0-59), heure (0-23), jour du mois (1-31), mois (1-12) et jour de la semaine (0-6, où 0 est dimanche). Un astérisque (*) signifie « chaque » valeur pour ce champ.
Que signifie */5 en cron ?
La syntaxe */5 signifie « toutes les 5 ». Dans le champ minute, */5 signifie toutes les 5 minutes (0, 5, 10, 15...). Dans le champ heure, */5 signifie toutes les 5 heures. Cela fonctionne dans n'importe quel champ.
Les expressions cron sont-elles identiques sur toutes les plateformes ?
Le format à 5 champs est standard sur Linux cron, AWS EventBridge, GitHub Actions et la plupart des systèmes de planification. Certaines plateformes ajoutent un 6e champ pour les secondes ou l'année. Consultez la documentation de votre plateforme.
Comment planifier pour le dernier jour de chaque mois ?
Le cron standard n'a pas de mot-clé « dernier jour ». Utilisez un contournement comme une exécution quotidienne avec une vérification de date dans votre script, ou utilisez des extensions propres à la plateforme (AWS EventBridge supporte L pour « last »).
Why did my cron job not run at the expected time?
The most common cause is timezone confusion. Server cron usually runs in UTC, not your local time. Other causes include the server being asleep at the scheduled minute, the user crontab not being installed, or PATH/environment differences between your shell and cron's stripped-down environment.
What is the difference between 0 in the day-of-week field and 7?
Both 0 and 7 represent Sunday in classic Vixie cron, which uses 0-6 plus an alias for 7. Some implementations (notably AWS EventBridge) use 1-7 with Sunday as 7 and Monday as 1, so always check your platform's documentation before assuming.