Guides 8 min de lecture

Expressions cron expliquées : syntaxe, exemples et erreurs courantes

Une expression cron, ce sont cinq champs qui indiquent quand une tâche s’exécute. La syntaxe, les caractères spéciaux et les raccourcis comme @daily, des exemples prêts à l’emploi et les erreurs de fuseau horaire et de PATH qui font échouer les tâches.

Une expression cron se compose de cinq champs séparés par des espaces : minute, heure, jour du mois, mois et jour de la semaine, suivis de la commande à exécuter. 30 2 * * * signifie « à 02:30 tous les jours ». Chaque champ accepte un nombre, un * pour « toutes les valeurs », une liste séparée par des virgules, une plage avec un trait d’union ou un pas avec une barre oblique. La plupart des problèmes de cron ne viennent pas de la syntaxe elle-même, mais de ce qui l’entoure : le fuseau horaire du serveur, la règle qui combine jour du mois et jour de la semaine, et l’environnement minimal dans lequel cron exécute les commandes.

Ce guide détaille chaque champ et chaque caractère spécial, propose un tableau d’expressions prêtes à l’emploi et passe en revue les erreurs qui font tourner les tâches au mauvais moment, voire pas du tout.

Les cinq champs

Chaque ligne d’une crontab utilisateur suit la même structure :

┌───────────── minute (0–59)
│ ┌─────────── heure (0–23)
│ │ ┌───────── jour du mois (1–31)
│ │ │ ┌─────── mois (1–12 ou JAN–DEC)
│ │ │ │ ┌───── jour de la semaine (0–7 ou SUN–SAT, 0 et 7 sont tous deux dimanche)
│ │ │ │ │
* * * * * /path/to/command

Une tâche s’exécute quand la minute en cours correspond à tous les champs, à une exception près pour les deux champs de jour, présentée plus bas. Les mois et les jours de la semaine peuvent s’écrire avec leur nom anglais en trois lettres, sans tenir compte de la casse.

Vous modifiez votre propre crontab avec crontab -e et l’affichez avec crontab -l. Les fichiers système, /etc/crontab et les fichiers de /etc/cron.d/, ont un sixième champ entre la planification et la commande : l’utilisateur sous lequel la tâche s’exécute. Copier une ligne d’un format à l’autre sans ajouter ou retirer ce champ est un grand classique pour casser une tâche.

Les caractères spéciaux

CaractèreSignificationExempleRésultat*Toutes les valeurs* * * * *Toutes les minutes,Liste de valeurs0 8,12,18 * * *À 08:00, 12:00 et 18:00-Plage0 9 * * 1-509:00 du lundi au vendredi/Pas*/15 * * * *Minutes 0, 15, 30 et 45

Comment fonctionnent vraiment les pas

Un pas découpe la plage d’un champ à partir de sa première valeur. */15 dans le champ des minutes signifie 0, 15, 30 et 45. Un pas peut aussi s’appliquer à une plage : 0-30/10 signifie les minutes 0, 10, 20 et 30.

Les pas repartent de zéro à la limite du champ. */7 dans le champ des minutes s’exécute à 0, 7, 14 et ainsi de suite jusqu’à 56, puis de nouveau à 0 : le dernier intervalle de chaque heure ne dure donc que quatre minutes. */7 ne veut pas dire « toutes les sept minutes ». Le cron classique ne sait pas non plus exprimer « toutes les 90 minutes » en une seule ligne ; il faut deux lignes ou une vérification dans le script.

La syntaxe qui n’est pas du cron classique

Vous croiserez peut-être L (dernier), W (jour ouvré le plus proche), # (n-ième jour de la semaine du mois) et ? dans certaines documentations. Ils viennent de Quartz et de certains planificateurs cloud et CI, pas du cron d’un serveur Linux, et certains de ces planificateurs ajoutent aussi un champ des secondes au début. Beaucoup d’implémentations de cron refusent aussi les plages de noms : écrivez 1-5 plutôt que MON-FRI.

Les raccourcis comme @daily

La plupart des implémentations de cron sous Linux acceptent un raccourci nommé à la place des cinq champs :

@reboot : une fois, quand le démon cron démarre après un redémarrage.

@yearly ou @annually : 0 0 1 1 *, à minuit le 1er janvier.

@monthly : 0 0 1 * *, à minuit le premier du mois.

@weekly : 0 0 * * 0, à minuit entre samedi et dimanche.

@daily ou @midnight : 0 0 * * *.

@hourly : 0 * * * *.

Tous les raccourcis se déclenchent à l’heure pile ou à minuit : sur un serveur chargé, toutes les tâches se disputent donc les mêmes ressources à 00:00. Écrire l’expression complète avec une minute décalée, comme 17 0 * * *, répartit la charge.

Des expressions cron prêtes à l’emploi

ExpressionExécution* * * * *Toutes les minutes*/5 * * * *Toutes les 5 minutes*/15 * * * *Toutes les 15 minutes0 * * * *Toutes les heures, à l’heure pile15 */2 * * *À la minute 15 toutes les deux heures : 00:15, 02:15, 04:15 et ainsi de suite0 9-17 * * 1-5Toutes les heures de 09:00 à 17:00, du lundi au vendredi*/10 8-18 * * 1-5Toutes les 10 minutes pendant les heures de bureau en semaine30 2 * * *Tous les jours à 02:300 8,12,18 * * *Trois fois par jour : 08:00, 12:00 et 18:000 6 * * 1Tous les lundis à 06:000 22 * * 5Tous les vendredis à 22:000 0 * * 0Tous les dimanches à minuit0 3 1 * *Le premier jour de chaque mois à 03:000 4 1,15 * *Le 1er et le 15 de chaque mois à 04:000 5 1 */3 *Chaque trimestre : le 1er janvier, avril, juillet et octobre à 05:000 0 1 1 *Une fois par an, à minuit le 1er janvier@rebootUne fois après chaque démarrage du système

Une erreur fréquente avec cette liste : * */2 * * *. Cette expression ne s’exécute pas toutes les deux heures. Elle s’exécute toutes les minutes, une heure sur deux, soixante fois d’affilée. Quand vous restreignez l’heure, fixez toujours aussi la minute.

Jour du mois et jour de la semaine : la règle du OU

Tous les champs sont combinés avec un ET, sauf les deux champs de jour. Quand le jour du mois et le jour de la semaine sont tous deux restreints, c’est-à-dire qu’aucun n’est *, la tâche s’exécute dès que l’un ou l’autre correspond. Ainsi, cette ligne :

0 9 1 * 1 /usr/local/bin/report.sh

s’exécute à 09:00 le premier de chaque mois et à 09:00 tous les lundis, pas seulement les lundis qui tombent le 1er. Pour la même raison, 0 9 1-7 * 1 ne signifie pas « le premier lundi du mois » : elle s’exécute du 1er au 7 et tous les lundis. Pour obtenir le premier lundi, planifiez les jours 1 à 7 et vérifiez le jour de la semaine dans la commande. Notez le signe pourcentage échappé, expliqué plus bas :

0 9 1-7 * * [ « $(date +\%u) » = « 1 » ] && /usr/local/bin/report.sh

Le cron classique ne connaît pas non plus le « dernier jour du mois ». Avec la commande date de GNU, planifiez les jours 28 à 31 et n’exécutez la tâche que si le lendemain est le 1er :

0 23 28-31 * * [ « $(date -d tomorrow +\%d) » = « 01 » ] && /usr/local/bin/month-end.sh

Fuseaux horaires et heure d’été

Cron utilise le fuseau horaire du système sur lequel il tourne. Une tâche écrite pour l’heure de Stockholm sur un serveur réglé en UTC démarre avec une ou deux heures de décalage, selon la saison. Vérifiez le fuseau du serveur avec timedatectl ou date avant de choisir une planification. Utilisez le même fuseau pour surveiller la tâche : les moniteurs cron d’Uptimecheck prennent la planification de la crontab avec un fuseau horaire, pour que les heures d’exécution attendues correspondent à celles du serveur.

Certaines implémentations, comme cronie, acceptent une variable CRON_TZ en haut de la crontab pour exécuter les planifications dans un autre fuseau. La prise en charge varie selon les versions de cron : testez-la plutôt que de supposer qu’elle fonctionne.

Le passage à l’heure d’été provoque les bugs les plus étranges. Au printemps, une heure locale n’existe pas ; à l’automne, une heure se produit deux fois. Une tâche planifiée entre 01:00 et 03:00 environ, heure locale, peut être sautée, retardée ou exécutée deux fois, et chaque implémentation de cron gère le changement à sa manière. Les options les plus sûres :

Faites tourner les serveurs en UTC, qui n’a pas d’heure d’été, et faites la conversion de tête ou dans un commentaire.

Si le serveur doit rester à l’heure locale, placez les tâches importantes en dehors des heures de changement d’heure.

Indiquez le fuseau horaire dans un commentaire au-dessus de chaque tâche, pour que la personne suivante n’ait pas à deviner.

Rendez les tâches sûres à exécuter deux fois, par exemple en vérifiant si l’export du jour existe déjà.

Les pièges de l’environnement et du PATH

Une commande qui fonctionne dans votre terminal et échoue sous cron échoue presque toujours à cause de l’environnement. Cron ne charge pas le profil de votre shell, donc une bonne partie de ce que vous tenez pour acquis manque :

Le PATH est minimal, souvent juste /usr/bin:/bin. Les commandes de /usr/local/bin, ou les outils installés avec nvm, pyenv, rbenv ou Composer, sont introuvables. Utilisez des chemins absolus ou définissez PATH en haut de la crontab.

Le shell est /bin/sh, pas bash. La syntaxe propre à bash comme [[ ]] ou source échoue. Définissez SHELL=/bin/bash ou placez la logique dans un script avec un shebang bash.

Le signe pourcentage est spécial. Dans une ligne de crontab, % est converti en saut de ligne. date +%F doit s’écrire date +\%F, ou être déplacé dans un script.

Le répertoire de travail est le dossier personnel de l’utilisateur, pas votre projet. Les chemins relatifs pointent au mauvais endroit. Faites d’abord un cd dans le projet.

Les variables d’environnement ont disparu. Les clés d’API et URL de base de données exportées dans .bashrc n’existent pas. Chargez-les depuis un fichier dans le script.

La sortie se perd. Cron envoie la sortie par e-mail à MAILTO si la messagerie est configurée, ce qui n’est pas le cas sur la plupart des serveurs. Redirigez la sortie vers un fichier journal.

Les exécutions peuvent se chevaucher. Si une tâche lancée toutes les cinq minutes en prend parfois sept, deux copies tournent en même temps. flock -n saute une exécution tant que la précédente détient le verrou.

Certaines versions de cron ignorent aussi une dernière ligne qui ne se termine pas par un saut de ligne. Une crontab qui gère tout cela ressemble à ceci :

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO= » »

# Sauvegarde nocturne de la base de données. Le serveur est en UTC.
30 2 * * * cd /var/www/fjordstudio && flock -n /tmp/backup.lock ./bin/backup.sh >> /var/log/backup.log 2>&1

Comment tester une expression cron

Relisez-la en toutes lettres. Collez l’expression dans un analyseur d’expressions cron et vérifiez que la description et les prochaines exécutions correspondent à ce que vous vouliez.

Lancez la commande dans l’environnement de cron. Un environnement épuré reproduit la plupart des échecs du type « ça marche dans mon terminal » avant même d’attendre la planification.

Planifiez-la une fois toutes les minutes. Utilisez * * * * * temporairement, regardez-la s’exécuter, puis définissez la vraie planification.

Vérifiez que cron l’a bien lancée. Sous Debian et Ubuntu, grep CRON /var/log/syslog ou journalctl -u cron ; sur les systèmes basés sur Red Hat, /var/log/cron ou journalctl -u crond.

Confirmez que la crontab est installée avec crontab -l, en tant qu’utilisateur qui doit l’exécuter.

Pour simuler l’environnement de cron depuis un shell :

env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME= »$HOME » /bin/sh -c ‘/usr/local/bin/backup.sh’

Associez chaque tâche à un heartbeat

Une expression correcte indique seulement à cron quand lancer une tâche. Elle ne dit rien sur le fait que la tâche se soit exécutée ou terminée. Un redémarrage, une crontab écrasée ou une variable manquante échouent tous en silence.

Un heartbeat comble cette lacune. La tâche appelle une URL unique quand elle se termine avec succès, et le service de surveillance vous alerte quand l’appel n’arrive pas à l’heure prévue :

30 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 –retry 3 https://heartbeat.example.com/your-unique-id > /dev/null

Réglez l’intervalle attendu du heartbeat sur la même planification que l’expression cron, avec une marge pour les exécutions lentes : 24 heures et un peu plus pour une tâche nocturne, une heure et un peu plus pour une tâche horaire. La surveillance des tâches cron d’Uptimecheck fonctionne ainsi, avec des alertes quand un ping manque et une notification de rétablissement quand la tâche se manifeste à nouveau. Ses moniteurs cron prennent la planification de la crontab dans votre fuseau horaire, acceptent des pings de début et de fin sur un même moniteur, alertent quand une exécution dépasse sa durée maximale et peuvent enregistrer le code de sortie et la sortie de la tâche. Le guide surveiller les tâches cron avec des heartbeats détaille la mise en place, et éviter les tâches cron manquées couvre les bonnes pratiques qui l’accompagnent.

Quand un heartbeat manque à l’appel, la cause se trouve souvent sur le serveur : un disque plein, une mémoire saturée ou un redémarrage imprévu. La surveillance des serveurs, à côté de vos heartbeats, révèle cette cause au même moment.

Check-list des erreurs courantes

Restreindre l’heure en laissant la minute à *.

Renseigner les deux champs de jour en s’attendant à un ET au lieu d’un OU.

Supposer que le serveur est dans votre fuseau horaire.

Planifier des tâches importantes pendant l’heure du changement d’heure.

Utiliser des chemins relatifs, de la syntaxe bash ou un % non échappé.

Faire tourner une tâche sans heartbeat, si bien que personne ne remarque quand elle s’arrête.

En résumé

Cinq champs, quatre caractères spéciaux et une poignée de raccourcis couvrent presque toutes les planifications dont vous aurez besoin. L’expression est rarement le problème. Les fuseaux horaires, la règle du OU pour les champs de jour et l’environnement dépouillé de cron, si. Notez le fuseau horaire à côté de chaque tâche, utilisez des chemins absolus, journalisez la sortie et donnez un heartbeat à chaque tâche qui compte.

Les heartbeats d’Uptimecheck sont inclus dans tous les plans, y compris le plan Free, aux côtés de la surveillance de disponibilité, SSL, de domaine et DNS. Démarrez un essai gratuit de 14 jours, sans carte bancaire.

Questions

Que signifie */5 * * * * dans cron ?

Toutes les cinq minutes : aux minutes 0, 5, 10 et ainsi de suite jusqu’à 55 de chaque heure, tous les jours.

Comment exécuter une tâche cron toutes les deux heures ?

Utilisez 0 */2 * * *, qui s’exécute à la minute 0 toutes les deux heures. Écrire * */2 * * * exécute au contraire la tâche toutes les minutes, une heure sur deux.

Quel fuseau horaire cron utilise-t-il ?

Le fuseau horaire du système sur lequel il tourne. Beaucoup de serveurs cloud et de conteneurs sont en UTC : vérifiez avec timedatectl ou date avant de choisir une planification. Certaines implémentations prennent en charge une variable CRON_TZ.

Pourquoi ma tâche cron fonctionne-t-elle dans le terminal mais pas dans cron ?

Cron exécute les commandes avec un PATH minimal, /bin/sh comme shell, le dossier personnel comme répertoire de travail et sans le profil de votre shell. Utilisez des chemins absolus, échappez les signes % et journalisez la sortie pour voir l’erreur.

À lire aussi

Guides 6 min de lecture

Comment surveiller vos tâches cron avec des heartbeats

Les tâches cron échouent en silence. Un moniteur heartbeat vous alerte quand une tâche planifiée ne se signale pas à temps. Fonctionnement des heartbeats, ajout dans une crontab et réglages à choisir.

Lire

Les pannes, c’est du passé.

Configurez votre premier moniteur en moins d’une minute, ou explorez d’abord la démo en ligne.

Essai gratuit de 14 jours · Puis gratuit pour 5 moniteurs · Sans carte bancaire