Cron et crontab : planifier des tâches sur un serveur
Écrire une crontab fiable : champs, utilisateur, PATH, fuseau, sorties, %, verrouillage flock et frontière avec systemd timers.
Serveurs dédiés, infogérance et migration
Il couvre les serveurs dédiés, l'infogérance, le stockage, la supervision et les plans de sortie.
Une tâche cron fiable ne se résume pas à cinq astérisques. Choisissez d’abord la bonne crontab, écrivez des chemins absolus, définissez environnement et sorties, testez la commande sous le compte réel, puis empêchez les chevauchements. Pour les dépendances, reprises après arrêt et journaux structurés, préférez parfois un timer systemd.
Choisir entre crontab utilisateur et fichier système
Le format change selon l’emplacement. La commande crontab -e édite la table du compte courant : cinq champs temporels, puis la commande. /etc/crontab et les fichiers de /etc/cron.d ajoutent un champ utilisateur avant la commande.
# crontab utilisateur
15 2 * * * /home/alice/bin/sauvegarde
# /etc/cron.d/sauvegarde
15 2 * * * alice /home/alice/bin/sauvegarde
Dans /etc/cron.d, le fichier doit être contrôlé par root et ne pas être modifiable par le groupe ou les autres utilisateurs. Sur Debian, chaque fichier est indépendant et n’hérite pas des variables posées dans /etc/crontab.

Lire les cinq champs temporels
| Champ | Valeurs usuelles | Exemple |
|---|---|---|
| Minute | 0 à 59 | 15 |
| Heure | 0 à 23 | 2 |
| Jour du mois | 1 à 31 | * |
| Mois | 1 à 12 | * |
| Jour de semaine | 0 à 7, dimanche 0 ou 7 | 1-5 |
La ligne suivante s’exécute à 02:15 du lundi au vendredi :
15 2 * * 1-5 /home/alice/bin/sauvegarde
Si jour du mois et jour de semaine sont tous deux restreints, de nombreuses implémentations cron déclenchent lorsqu’au moins l’un correspond. N’écrivez pas une combinaison complexe sans la vérifier dans la page man locale. Les extensions comme CRON_TZ, RANDOM_DELAY ou certains raccourcis ne sont pas universelles.
Reproduire l’environnement minimal
Cron n’ouvre pas votre shell interactif et ne charge pas forcément ses profils. Définissez au minimum SHELL, PATH, HOME utile et destination des sorties.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=ops@example.net
15 2 * * * /home/alice/bin/sauvegarde
MAILTO demande un système de courrier fonctionnel. Si aucun MTA n’est configuré, une sortie importante peut disparaître sans destinataire. Une alternative consiste à envoyer stdout et stderr vers le journal du service ou un fichier géré par logrotate.
15 2 * * * /home/alice/bin/sauvegarde >>/var/log/sauvegarde.log 2>&1
Le répertoire courant, les variables et les droits doivent être explicites. Dans le script, utilisez des chemins absolus, un umask adapté et un code de sortie non nul en cas d’échec.
Testez sous le compte exact avec un environnement réduit :
sudo -u alice env -i \
HOME=/home/alice \
PATH=/usr/local/bin:/usr/bin:/bin \
SHELL=/bin/sh \
/home/alice/bin/sauvegarde
Guillemets, shell et caractère pourcentage
La partie commande est exécutée par /bin/sh, sauf SHELL différent. Les règles de citation sont donc celles de ce shell, mais cron ajoute un piège : un caractère % non échappé devient un saut de ligne, et le reste est envoyé à l’entrée standard de la commande.
Une date contenant % doit l’échapper dans une crontab classique :
5 0 * * * /usr/bin/date '+\%F' >>/var/log/date-cron.log
Placez les pipelines complexes dans un script versionné et testé. Cela évite plusieurs niveaux de guillemets, rend shellcheck possible et donne un point clair pour les logs et le verrouillage.
Fuseau horaire et changements d’heure
Le daemon travaille généralement dans le fuseau du système. Certaines implémentations acceptent CRON_TZ pour une table :
CRON_TZ=Europe/Paris
15 2 * * * /home/alice/bin/sauvegarde
Une heure locale peut ne pas exister au passage à l’heure d’été ou apparaître deux fois au retour. Le comportement exact dépend du daemon. Pour une tâche métier, choisissez consciemment entre heure locale et UTC, rendez le traitement idempotent et enregistrez l’instant traité.
Empêcher deux exécutions simultanées
Cron déclenche selon l’horloge ; il n’attend pas la fin de l’instance précédente. util-linux flock peut refuser un deuxième lancement :
*/5 * * * * /usr/bin/flock -n /run/user/1000/import.lock /home/alice/bin/import
Le répertoire de verrou doit être accessible au compte et persister assez longtemps pour le besoin. Pour une tâche système, créez un chemin de lock détenu par le compte du service. L’option -n échoue immédiatement si le verrou existe ; capturez ce code dans la supervision.
| Risque | Contrôle | Preuve |
|---|---|---|
| Instance précédente active | flock -n | Code de conflit journalisé |
| Commande introuvable | PATH et chemins absolus | Test avec env -i |
| Sortie perdue | MAILTO ou journal explicite | Alerte de test reçue |
| Horaire ambigu | Fuseau documenté | Horodatage de dernière exécution |
Un verrou évite le chevauchement, pas un script non idempotent. Prévoyez fichiers temporaires atomiques, reprises contrôlées et état vérifiable.
Vérifier la crontab avant d’attendre
Vérifiez la table installée, pas seulement le fichier préparé. Affichez-la ainsi :
crontab -l
sudo crontab -u alice -l
systemctl status cron
Selon la distribution, le service peut s’appeler crond. Consultez les journaux du daemon et ceux de la commande. Pour tester, utilisez un horaire proche avec une action sans danger, puis retirez la ligne après preuve. Évitez de tester une sauvegarde réelle ou une suppression sur des données de production.
Quand préférer un timer systemd
Un timer systemd devient plus lisible lorsque la tâche dépend d’un montage ou du réseau, doit rattraper une exécution manquée, possède des limites de ressources, ou doit écrire dans le journal avec un état de service distinct.
Persistent=true peut rattraper une échéance manquée pendant l’arrêt, et RandomizedDelaySec répartit des tâches identiques. En échange, il faut maintenir une unité .service et une unité .timer. Cron reste adapté aux petites tâches portables à calendrier simple.
Sur un VPS, le choix dépend aussi du redémarrage et des fenêtres de maintenance. Une tâche quotidienne qui doit absolument s’exécuter après un arrêt prolongé mérite une reprise explicite, pas l’espoir que cron reconstruise le passé.
À conserver dans la fiche d’exploitation :
- emplacement et propriétaire de la planification ;
- fuseau, PATH, secrets injectés et destination des sorties ;
- durée maximale, lock et comportement en conflit ;
- commande de test, code de sortie et procédure de désactivation.
Liste de contrôle
- Choisissez crontab utilisateur ou fichier système et le bon nombre de champs.
- Définissez PATH, SHELL, fuseau et sortie de façon explicite.
- Testez le script sous le compte réel avec environnement réduit.
- Ajoutez un verrou si la durée peut dépasser l’intervalle.
- Vérifiez journaux et alerte, ou basculez vers systemd timer si nécessaire.
Questions fréquentes
Pourquoi ma commande fonctionne-t-elle dans le terminal mais pas dans cron ?
Pourquoi /etc/cron.d contient-il un champ de plus ?
Que fait le caractère % dans une commande cron ?
Cron relance-t-il une tâche manquée pendant l’arrêt ?
Préparé par
Serveurs dédiés, infogérance et migration
Il couvre les serveurs dédiés, l'infogérance, le stockage, la supervision et les plans de sortie.
Faits vérifiés
HostScout editorialArticles liés
Fail2ban : configurer un bannissement vérifiable
Configurez Fail2ban sans faux sentiment de sécurité : journaux, jail.local, backend systemd, seuils, tests, déban, IPv6 et proxy inverse.
UFW : configurer le pare-feu sans perdre SSH
Configurez UFW dans le bon ordre : port SSH réel, politiques, IPv4 et IPv6, profils, journaux, suppression de règles et limite Docker.
Vérifier l’espace disque sous Linux avec df et du
Diagnostiquer un disque Linux plein avec df, du, findmnt, les inodes, lsof et journalctl sans supprimer des données au hasard.
Clés SSH : l’authentification sans mot de passe
Créer une clé SSH Ed25519, installer la clé publique, vérifier l’hôte et désactiver le mot de passe sans perdre l’accès.
Installer Zabbix pour superviser ses serveurs
Installer Zabbix 7.0 LTS sur Ubuntu 24.04 avec PostgreSQL, Nginx et Agent 2, puis sécuriser et valider chaque composant.
MySQL : créer un utilisateur et gérer les droits
Créer un utilisateur MySQL 8.4, limiter son hôte, attribuer puis retirer des droits, imposer TLS et contrôler le résultat.