Aller au contenu
Administration Linux medium

Planifier des tâches avec cron et crontab sous Linux

50 min de lecture

cron est le planificateur de tâches historique de Linux. Il exécute des commandes à des intervalles définis, toutes les minutes, chaque jour à 3 h, chaque lundi, selon une syntaxe à 5 champs. C'est l'outil de base pour automatiser les sauvegardes, le nettoyage de fichiers, les synchronisations et toute opération récurrente sur un serveur.

  • Comprendre le fonctionnement du démon cron et ses fichiers de configuration
  • Lire et écrire la syntaxe à 5 champs d'une ligne crontab
  • Créer, modifier et supprimer des crontabs utilisateur avec crontab -e
  • Utiliser les répertoires système /etc/cron.d/, /etc/cron.daily/ etc.
  • Diagnostiquer une tâche cron qui ne s'exécute pas
  • Appliquer les bonnes pratiques de sécurité et de fiabilité

cron intervient dès qu'une action doit se répéter automatiquement sur un système Linux :

  • Sauvegarder une base de données ou un répertoire chaque nuit
  • Nettoyer les fichiers temporaires ou les logs obsolètes
  • Synchroniser des données entre serveurs avec rsync
  • Renouveler un certificat Let's Encrypt
  • Envoyer un rapport par e-mail chaque semaine
  • Vérifier l'espace disque et alerter si un seuil est dépassé

Le démon cron (crond sur Red Hat, cron sur Debian/Ubuntu) tourne en permanence. Chaque minute, il vérifie :

  1. Les crontabs utilisateur, éditées avec crontab -e, stockées dans /var/spool/cron/crontabs/ sur Debian et Ubuntu, directement dans /var/spool/cron/ sur RHEL et AlmaLinux
  2. Le fichier /etc/crontab, la crontab système
  3. Les fichiers dans /etc/cron.d/, des crontabs supplémentaires déposées par les paquets
  4. Les répertoires /etc/cron.{hourly,daily,weekly,monthly}/, des scripts exécutés par run-parts
Fenêtre de terminal
# Debian/Ubuntu
systemctl status cron
# RHEL/Fedora/Rocky/Alma
systemctl status crond
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; preset: enabled)
Active: active (running)

Une crontab est un fichier texte où chaque ligne non commentée décrit une tâche : cinq champs de temps, puis la commande à lancer. Le démon compare ces cinq champs à l'horloge une fois par minute, et exécute la commande quand ils correspondent tous. La minute est donc l'unité la plus fine possible, cron ne sait pas déclencher toutes les dix secondes.

Chaque ligne d'une crontab suit ce format :

┌───────────── minute (0-59)
│ ┌───────────── heure (0-23)
│ │ ┌───────────── jour du mois (1-31)
│ │ │ ┌───────────── mois (1-12)
│ │ │ │ ┌───────────── jour de la semaine (0-7, 0 et 7 = dimanche)
│ │ │ │ │
* * * * * commande à exécuter

Chacun des cinq champs accepte les mêmes opérateurs, qui se combinent entre eux (0,30 8-18 * * 1-5 reste valide). Retenez surtout que les champs sont liés par un ET logique, sauf le jour du mois et le jour de la semaine : si ces deux champs sont renseignés en même temps, cron exécute la tâche dès que l'un ou l'autre correspond. C'est la source d'exécutions surprises, indiquez * dans l'un des deux tant que vous n'avez pas besoin de ce comportement.

OpérateurSignificationExemple
*Toutes les valeurs* * * * * = chaque minute
,Liste de valeurs1,15 * * * * = aux minutes 1 et 15
-Plage1-5 * * * * = minutes 1 à 5
/Pas (intervalle)*/10 * * * * = toutes les 10 minutes

Lisez toujours une expression de gauche à droite, en commençant par la minute. L'erreur la plus courante consiste à écrire * 3 * * * en pensant « à 3 h » : cette ligne lance la commande soixante fois, à chaque minute entre 3 h 00 et 3 h 59. Pour un déclenchement unique à une heure donnée, le champ minute doit porter une valeur précise, ici 0 3 * * *.

ExpressionSignification
0 3 * * *Chaque jour à 3 h 00
30 8 * * 1-5Du lundi au vendredi à 8 h 30
0 */2 * * *Toutes les 2 heures (à minute 0)
0 0 1 * *Le 1er de chaque mois à minuit
*/5 * * * *Toutes les 5 minutes
0 22 * * 0Chaque dimanche à 22 h

cron reconnaît aussi des raccourcis qui remplacent les 5 champs :

RaccourciÉquivalentSignification
@reboot-Au démarrage du système
@hourly0 * * * *Chaque heure
@daily0 0 * * *Chaque jour à minuit
@weekly0 0 * * 0Chaque dimanche à minuit
@monthly0 0 1 * *Le 1er du mois à minuit
@yearly0 0 1 1 *Le 1er janvier à minuit

Chaque compte du système dispose de sa propre crontab, un fichier que l'on ne modifie jamais directement. Son emplacement dépend de la distribution : /var/spool/cron/crontabs/<utilisateur> sur Debian et Ubuntu, /var/spool/cron/<utilisateur> sur RHEL et AlmaLinux, où le sous-répertoire crontabs/ n'existe pas. Sur RHEL, le fichier porte en plus le contexte SELinux user_cron_spool_t, ce qui interdit de le déposer depuis un autre chemin sans réétiquetage. On passe par la commande crontab, qui vérifie la syntaxe avant d'enregistrer et prévient le démon du changement. Les tâches y sont exécutées sous l'identité du propriétaire du fichier, avec ses droits et rien de plus.

crontab -e ouvre une copie temporaire du fichier dans un éditeur, puis la réinstalle à la sauvegarde après validation syntaxique. Si une ligne est mal formée, la commande refuse l'enregistrement et vous propose de corriger, la crontab précédente reste en place.

Fenêtre de terminal
crontab -e

L'éditeur par défaut s'ouvre (défini par $EDITOR ou $VISUAL). Ajoutez vos lignes et sauvegardez.

crontab -l écrit le contenu du fichier sur la sortie standard, sans ouvrir d'éditeur. C'est la commande à utiliser pour vérifier ce qui est réellement planifié, et pour en faire une sauvegarde vers un fichier avant toute modification.

Fenêtre de terminal
crontab -l

crontab -r efface l'intégralité de la crontab de l'utilisateur courant, immédiatement et sans demander confirmation. Il n'existe aucune corbeille ni annulation : le fichier disparaît du répertoire de spool et les tâches cessent d'être planifiées à la minute suivante.

Fenêtre de terminal
crontab -r

L'option -u désigne le compte cible et n'est utilisable qu'avec les droits root. C'est la bonne façon de planifier une tâche applicative : elle tourne sous le compte de service (www-data, postgres) plutôt que sous root, ce qui limite les dégâts si le script part en erreur. Le fichier reste éditable ensuite par le compte concerné avec un simple crontab -e.

Fenêtre de terminal
sudo crontab -u www-data -e

À côté des crontabs personnelles, le système dispose de ses propres emplacements, alimentés par l'administrateur et par les paquets installés. Deux différences les distinguent d'une crontab utilisateur : ils comportent un champ utilisateur supplémentaire, et ils s'éditent comme des fichiers ordinaires, donc sans le contrôle de syntaxe de crontab -e. Une faute de frappe y passe inaperçue jusqu'à ce que la tâche ne se déclenche pas.

La crontab système contient un champ utilisateur supplémentaire :

# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || run-parts --report /etc/cron.daily
47 6 * * 7 root test -x /usr/sbin/anacron || run-parts --report /etc/cron.weekly
52 6 1 * * root test -x /usr/sbin/anacron || run-parts --report /etc/cron.monthly

Ce répertoire accueille des fichiers au format crontab (avec champ utilisateur). Les paquets y déposent leurs tâches planifiées :

Fenêtre de terminal
ls /etc/cron.d/
e2scrub_all popularity-contest sysstat

Les scripts placés dans ces répertoires sont exécutés automatiquement par run-parts :

RépertoireFréquence
/etc/cron.hourly/Chaque heure
/etc/cron.daily/Chaque jour
/etc/cron.weekly/Chaque semaine
/etc/cron.monthly/Chaque mois

cron exécute les commandes dans un environnement minimal. Le PATH est réduit, les variables de votre shell interactif ne sont pas disponibles.

Fenêtre de terminal
# Définir des variables en haut de la crontab
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
# La commande utilise le PATH complet
0 3 * * * /usr/local/bin/backup.sh
VariableEffet
SHELLShell utilisé pour exécuter les commandes
PATHRépertoires de recherche des commandes
MAILTODestinataire des sorties (vide = pas d'e-mail)
HOMERépertoire de travail (par défaut celui de l'utilisateur)

Deux fichiers contrôlent qui peut utiliser cron :

FichierEffet
/etc/cron.allowSi ce fichier existe, seuls les utilisateurs listés peuvent utiliser cron
/etc/cron.denyLes utilisateurs listés sont interdits (ignoré si cron.allow existe)

Si aucun des deux fichiers n'existe, le comportement dépend de la distribution :

  • Debian/Ubuntu : tous les utilisateurs peuvent utiliser cron
  • Red Hat/Rocky : seul root peut utiliser cron

Par défaut, cron envoie la sortie standard et d'erreur par e-mail (via MAILTO). Pour rediriger vers un fichier ou supprimer la sortie :

Fenêtre de terminal
# Rediriger stdout et stderr vers un fichier log
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# Supprimer toute sortie
0 3 * * * /usr/local/bin/backup.sh > /dev/null 2>&1
# Rediriger stderr uniquement vers un fichier
0 3 * * * /usr/local/bin/backup.sh 2>> /var/log/backup-errors.log

Les trois tâches ci-dessous couvrent les besoins récurrents d'un serveur : produire une sauvegarde, récupérer de l'espace disque, et alerter avant que le disque ne soit plein. Chacune illustre au passage une contrainte propre à cron, l'échappement du %, l'usage de chemins absolus, et la dépendance à un service de messagerie fonctionnel sur la machine.

Cette ligne datera l'archive du jour où elle s'exécute, à condition que le % soit échappé. Notez le chemin complet /usr/bin/tar : dans l'environnement réduit de cron, un simple tar peut ne pas être trouvé. Vérifiez aussi que /backup existe et que le compte propriétaire de la crontab a le droit d'y écrire, sinon la tâche échouera silencieusement chaque nuit.

Fenêtre de terminal
# Sauvegarde de /home chaque nuit à 2 h 30
30 2 * * * /usr/bin/tar czf /backup/home-$(date +\%Y\%m\%d).tar.gz /home

-mtime +7 sélectionne les fichiers dont le contenu n'a pas été modifié depuis plus de sept jours entiers ; un fichier simplement lu depuis n'est pas épargné. -type f restreint aux fichiers ordinaires, ce qui évite de s'attaquer aux répertoires et aux sockets que des services actifs utilisent encore. Testez toujours la commande sans -delete d'abord, la liste affichée vous dit exactement ce qui va disparaître.

Fenêtre de terminal
# Supprimer les fichiers de plus de 7 jours dans /tmp chaque jour à 4 h
0 4 * * * /usr/bin/find /tmp -type f -mtime +7 -delete

awk ignore la première ligne d'en-tête grâce à NR==2 et compare la cinquième colonne, celle du pourcentage d'occupation ; int($5) en retire le caractère % pour permettre la comparaison numérique. La commande mail n'envoie un message que si la condition est vraie, donc un serveur sain reste silencieux. Elle suppose un agent de transport de courrier installé et configuré localement, sans quoi l'alerte se perd sans laisser de trace.

Fenêtre de terminal
# Alerte si le disque dépasse 90 %, chaque heure
0 * * * * df -h / | awk 'NR==2 && int($5)>90 {print "ALERTE disque : "$5}' | mail -s "Disque plein" admin@example.com

Une tâche cron qui ne produit rien pose toujours la même question : le démon a-t-il tenté de l'exécuter, ou la commande a-t-elle échoué une fois lancée ? Le journal répond, car cron y écrit une ligne à chaque déclenchement, avec l'utilisateur et la commande. Si cette ligne existe, le problème est dans le script ou son environnement ; si elle est absente, il est dans la planification ou dans l'état du service.

SymptômeCause probableSolution
Tâche ne s'exécute pasPATH insuffisantUtiliser des chemins absolus ou définir PATH en haut de la crontab
date affiche %Y%m%d% non échappéRemplacer % par \% dans la crontab
Aucune sortie visibleSortie non redirigéeAjouter >> /var/log/tache.log 2>&1
Permission deniedScript non exécutablechmod +x /chemin/du/script.sh
Tâche ne tourne pas (utilisateur)Bloqué par cron.denyVérifier /etc/cron.allow et /etc/cron.deny
Service cron inactifDémon arrêtésudo systemctl enable --now cron (Debian/Ubuntu) ou sudo systemctl enable --now crond (RHEL-like)
Script fonctionne en CLI mais pas dans cronVariables d'environnement manquantesDéfinir SHELL, PATH, HOME en haut de la crontab
Fenêtre de terminal
# Debian/Ubuntu
journalctl -u cron --since "1 hour ago"
# RHEL/Fedora/Rocky/Alma
journalctl -u crond --since "1 hour ago"
# Debian/Ubuntu (rsyslog)
grep CRON /var/log/syslog | tail -20
# RHEL-like (fichier dédié)
grep CROND /var/log/cron | tail -20

Une tâche planifiée s'exécute sans personne devant l'écran : elle doit donc échouer bruyamment plutôt que discrètement. Ces règles visent trois risques concrets, la commande introuvable faute de PATH, l'erreur qui part dans le vide faute de redirection, et l'accumulation d'exécutions qui se chevauchent quand un traitement dure plus longtemps que son intervalle.

  • Chemins absolus partout, ne pas supposer un PATH complet
  • Gérer les sorties, rediriger vers un fichier log ou configurer MAILTO
  • Échapper le % dans les crontabs, toujours \%
  • Commenter les lignes, expliquer chaque tâche avec #
  • Tester manuellement avant d'ajouter une tâche, exécuter la commande en tant que l'utilisateur cron
  • Verrouiller les tâches longues, utiliser flock pour éviter les exécutions parallèles :
Fenêtre de terminal
# Empêcher les exécutions concurrentes avec flock
*/5 * * * * /usr/bin/flock -n /tmp/backup.lock /usr/local/bin/backup.sh
  • Limiter l'accès, utiliser /etc/cron.allow pour n'autoriser que les utilisateurs légitimes

La syntaxe à 5 champs ne s'ancre vraiment qu'en voyant une tâche tourner toute seule. Ce lab vous installe dans une VM où vous écrivez une crontab avec crontab -e, planifiez une tâche récurrente et prouvez son exécution en retrouvant ses traces dans le journal de cron.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • cron exécute des tâches à intervalles réguliers selon une syntaxe à 5 champs (minute, heure, jour, mois, jour de semaine)
  • crontab -e édite la crontab de l'utilisateur courant, crontab -l l'affiche, crontab -r la supprime
  • Les commandes cron s'exécutent dans un environnement minimal, toujours utiliser des chemins absolus
  • Le % doit être échappé en \% dans les crontabs
  • /etc/cron.d/ et /etc/cron.{daily,weekly,monthly}/ servent aux tâches système
  • /etc/cron.allow et /etc/cron.deny contrôlent l'accès à cron
  • Toujours gérer les sorties (redirection ou MAILTO) et verrouiller les tâches longues avec flock

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn