Linux : Programmer une tâche avec cron

 

Besoin d’automatiser une commande ou un script tous les jours, toutes les 5 minutes ou au démarrage du serveur ? cron est l’outil standard sous Linux pour planifier des tâches récurrentes. Dans ce guide pratique, on va voir comment créer sa première tâche en moins de 5 minutes, comprendre la syntaxe, éviter les pièges courants et dépanner un cron s’il ne tourne pas.

Dans cet article :

  • L’essentiel pour démarrer en 5 minutes
  • La syntaxe d’une crontab (5 champs + commande)
  • Créer, éditer et lister votre crontab utilisateur
  • Bonnes pratiques (chemins absolus, PATH, flock, venv)
  • Crontab système vs utilisateur
  • Dépannage et alternatives (systemd timers)

Pré-requis : un système Linux avec le service cron (Ubuntu, Debian, RHEL) et un accès shell.


L’essentiel

Éditer votre crontab utilisateur :

crontab -e

Ajouter une ligne “tous les jours à 2h” :

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

Vérifier ce qui est programmé :

crontab -l

Voir les logs (Ubuntu/Debian) :

# via journald
journalctl -u cron -f
# ou dans syslog
sudo grep CRON /var/log/syslog

Comprendre la syntaxe d’une crontab

Une ligne de crontab (utilisateur) a 5 champs de date/heure suivis de la commande :

min  heure  jour  mois  jour_sem  commande
0-59 0-23   1-31  1-12  0-7       ...
  • jour_sem : 0 ou 7 = dimanche, 1 = lundi, 6 = samedi
  • Astuce : * = toutes les valeurs, */5 = toutes les 5 unités, 1,15 = les 1 et 15, 1-5 = de 1 à 5

Exemples rapides :

  • Toutes les 5 minutes : */5 * * * * /path/script.sh
  • Tous les jours à 02:00 : 0 2 * * * /path/script.sh
  • Chaque lundi à 09:00 : 0 9 * * 1 /path/script.sh
  • Le 1er de chaque mois à 06:00 : 0 6 1 * * /path/script.sh
  • Au démarrage de la machine : @reboot /path/script.sh

Raccourcis utiles :

  • @hourly, @daily, @weekly, @monthly, @yearly, @reboot

Attention : la crontab système (/etc/crontab ou fichiers dans /etc/cron.d/) ajoute un champ “utilisateur” après les 5 champs temps. Exemple : 0 2 * * * root /path/script.sh.


Créer et éditer votre crontab utilisateur

  • Ouvrir : crontab -e (première fois, il peut vous demander l’éditeur : nano/vi)
  • Lister : crontab -l
  • Supprimer tout : crontab -r (dangereux, demandez confirmation avec -i)

Vos tâches tourneront avec vos droits utilisateur, via le service cron du système.


Bonnes pratiques

Chemins absolus uniquement : /usr/bin/python et /home/user/mon_script.py, pas python ni ./mon_script.py.

Définir un PATH et le shell en tête de la crontab si nécessaire :

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

Rediriger la sortie et les erreurs pour diagnostiquer :

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

Scripts exécutables + shebang :

#!/usr/bin/env bash
# votre script.sh

Puis :

chmod +x /path/script.sh

Éviter les chevauchements : utilisez flock pour qu’une tâche ne tourne pas en double si la précédente n’est pas finie :

*/5 * * * * flock -n /tmp/monjob.lock -c "/path/script_long.sh" >> /var/log/monjob.log 2>&1

Variables d’environnement : cron a un environnement minimal. Exportez ce dont vous avez besoin, ou sourcez votre venv :

# Exemple venv Python
*/10 * * * * source /home/user/.venv/bin/activate && python /home/user/app/job.py >> /var/log/app/job.log 2>&1

Fuseau horaire : cron utilise le fuseau du système. Vérifiez :

timedatectl

Exemples courants

Sauvegarde quotidienne à 2h :

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

Nettoyage des fichiers temporaires vieux de 7 jours (toutes les nuits) :

30 1 * * * find /var/tmp/app -type f -mtime +7 -delete

Dump d’une base PostgreSQL tous les jours à 3h15 :

15 3 * * * PGUSER=app PGPASSWORD=secret pg_dump -h 127.0.0.1 -d appdb -F c -f /backups/appdb-$(date +\%F).dump

Relancer un service au boot après 30 secondes :

@reboot sleep 30 && systemctl restart mon-service

Ping santé toutes les 5 minutes :

*/5 * * * * curl -fsS https://status.exemple.com/ping || echo "ping KO" >> /var/log/healthcheck.log

Cron système vs crontab utilisateur

  • Crontab utilisateur : crontab -e (pas de champ utilisateur)
  • Crontab système : /etc/crontab et /etc/cron.d/*.conf (nécessite root, contient un champ utilisateur)
  • Dossiers périodiques (pilotés par /etc/crontab via run-parts) : /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly
  • Machines qui ne tournent pas en continu (laptops) : anacron garantit l’exécution “à retardement” des tâches quotidiennes, hebdomadaires ou mensuelles.

Exemple d’entrée dans /etc/crontab :

# m h dom mon dow user  command
0 2 * * * root /usr/local/bin/backup.sh

Dépannage : pourquoi ma tâche ne s’exécute pas ?

Vérifiez les points suivants :

  • Le script est-il exécutable (chmod +x) et a-t-il un shebang correct ?
  • Les chemins sont-ils absolus (binaire, fichiers, venv) ?
  • Permissions : l’utilisateur de la crontab a-t-il le droit d’exécuter ou d’écrire où il faut ?
  • Journaux : voyez journalctl -u cron ou grep CRON /var/log/syslog.
  • Redirection mise en place (>> ... 2>&1) pour capturer les erreurs ?
  • Fin de ligne : le fichier crontab doit se terminer par un saut de ligne (évite que la dernière ligne soit ignorée).
  • Caractères spéciaux (% dans crontab) : échappez-les avec \% dans les commandes (ex: date +\%F).
  • Variables non définies : rappelez PATH, SHELL, variables d’appli.
  • Système différent : sur certains systèmes, le service s’appelle crond (ex: RHEL), adaptez systemctl status crond.

Alternative moderne : systemd timers

Sur des distributions modernes, les “timers” systemd offrent plus de contrôle (dépendances, sandboxing, calendriers OnCalendar=). Pour des besoins complexes, envisagez un service + timer systemd. Pour des tâches simples, cron reste parfait.


FAQ

Comment exécuter un script Python avec son venv ?

  • Utilisez le Python du venv en chemin absolu : /home/user/.venv/bin/python /home/user/app/job.py.

Puis-je limiter l’usage CPU/RAM ?

  • Enveloppez la commande avec systemd-run --scope -p MemoryMax=... -p CPUQuota=... ou utilisez nice / ionice.

Comment arrêter temporairement une tâche ?

  • Commentez la ligne dans crontab -e en la préfixant avec #.

Pour aller plus loin

Voir aussi