Skip to content
VDS · Applications et bots

Tâches planifiées : cron et timers systemd

Comment exécuter des tâches planifiées, pourquoi une tâche fonctionne manuellement mais reste silencieuse dans cron, et quand passer aux timers systemd.

Mis à jour le 23 août 2026

Sauvegardes, renouvellement de certificats, nettoyage des fichiers temporaires, rapports nocturnes : autant de tâches planifiées. Sous Linux, vous les résolvez de deux manières : le cron classique et les timers systemd.

Cron : prise en main rapide

Vous modifiez la planification d'un utilisateur comme ceci :

crontab -e
crontab -l

Le format d'une ligne est composé de cinq champs et d'une commande :

# min  hour  day  month  day-of-week  command
  0    4    *     *      *            /usr/local/bin/backup.sh
  */15 *    *     *      *            /usr/local/bin/check.sh
  30   3    *     *      0            /usr/bin/systemctl restart myapp

Raccourcis utiles : @daily, @hourly, @reboot. Pour vérifier que les tâches se sont exécutées :

grep CRON /var/log/syslog | tail -30
journalctl -u cron --since "1 hour ago"

Pourquoi un script fonctionne à la main mais pas dans cron

C'est le problème le plus courant, et la cause est presque toujours l'une des trois suivantes.

Environnement différent. Cron dispose d'un PATH minimal et d'aucune de vos variables issues de .bashrc. Utilisez des chemins complets vers les programmes et définissez les variables explicitement en haut du script ou dans la crontab :

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Répertoire différent. La tâche démarre dans le répertoire personnel de l'utilisateur, donc les chemins relatifs pointent ailleurs. Utilisez toujours des chemins absolus.

La sortie ne va nulle part. Une erreur s'est produite, mais personne ne l'a vue. Écrivez un journal :

0 4 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Deux autres petits points : le caractère % dans une ligne cron doit être échappé en \%, et un fichier crontab doit se terminer par un saut de ligne — sinon la dernière tâche est ignorée.

Vous devez vérifier de l'extérieur qu'une tâche s'est exécutée. Un cron silencieux est identique à un cron réussi. Mettez en place une vérification par push dans Uptime Kuma : le script envoie une requête vers une adresse à la fin, et s'il ne l'a pas fait depuis un jour, vous recevez une alerte.

Timers systemd

Lorsqu'une tâche est plus complexe qu'une simple commande, un timer est plus pratique : il dispose d'un journal, de dépendances, de limites de ressources et d'une protection contre l'exécution simultanée de deux copies.

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run nightly backup

[Timer]
OnCalendar=*-*-* 04:00:00
Persistent=true
RandomizedDelaySec=15m

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers
journalctl -u backup.service -n 50

Persistent=true rattrape une exécution manquée si la machine était éteinte — ce que cron ne sait pas faire. RandomizedDelaySec répartit la charge pour qu'une dizaine de tâches ne démarrent pas à la même seconde.

Points à garder en tête

  • L'heure de la machine est en UTC par défaut. Vérifiez timedatectl avant de fixer « 4 h du matin ».
  • Les tâches lourdes (archives, vérification des sauvegardes) sollicitent le disque. Consultez la vitesse du disque et planifiez-les pour la nuit.
  • Une tâche longue exécutée toutes les cinq minutes va se chevaucher avec elle-même. Dans systemd, Type=oneshot aide ; dans cron, utilisez un verrou via flock :
*/5 * * * * /usr/bin/flock -n /tmp/job.lock /usr/local/bin/job.sh