ITSkillsCenter
Blog

Automatiser ses tâches avec cron sur Linux : tutoriel pas à pas pour PME

11 دقائق للقراءة

Ce que vous saurez faire

Ce tutoriel vous apprend a utiliser cron, le planificateur de taches Unix/Linux, pour automatiser les operations recurrentes de votre PME senegalaise. Que vous deviez sauvegarder votre base de donnees chaque nuit a 2h, envoyer un rapport de ventes chaque lundi matin a l’equipe, renouveler vos certificats SSL tous les 60 jours, nettoyer les fichiers temporaires, ou synchroniser votre stock vers le cloud toutes les heures, cron est l’outil incontournable. Vous apprendrez la syntaxe crontab exacte (avec ses pieges), comment editer votre crontab utilisateur et celui du systeme, les bonnes pratiques pour les variables d’environnement, les redirections de sortie indispensables, et comment deboguer un cron qui ne se declenche pas. A la fin, vous saurez aussi quand preferer systemd timers qui offrent des fonctionnalites avancees comme les dependances et le catch-up.

Etape 1 : Verifier que cron est actif

Cron est generalement installe par defaut. Verifiez que le service tourne avant de planifier.

# Statut du service cron
sudo systemctl status cron
# Ubuntu/Debian : cron
# CentOS/Rocky : crond

sudo systemctl status crond    # Si CentOS

# Activer au demarrage
sudo systemctl enable cron
sudo systemctl start cron

# Verifier l'installation
which crontab
# /usr/bin/crontab

# Aide
man crontab
man 5 crontab    # Documentation de la syntaxe

Etape 2 : Comprendre la syntaxe crontab

Une ligne crontab comporte 5 champs temporels suivis de la commande. Retenez l’ordre : minute, heure, jour du mois, mois, jour de la semaine.

# Structure generale
# *  *  *  *  *  commande
# |  |  |  |  |
# |  |  |  |  +---- jour de la semaine (0-6, 0=dimanche, ou mon,tue,wed...)
# |  |  |  +------- mois (1-12, ou jan,feb,mar...)
# |  |  +---------- jour du mois (1-31)
# |  +------------- heure (0-23)
# +---------------- minute (0-59)

# Exemples concrets :
# Chaque minute
* * * * * /usr/local/bin/check.sh

# Tous les jours a 2h30
30 2 * * * /usr/local/bin/backup.sh

# Tous les lundis a 9h00
0 9 * * 1 /usr/local/bin/rapport_semaine.sh

# Le 1er de chaque mois a 0h
0 0 1 * * /usr/local/bin/rapport_mois.sh

Etape 3 : Operateurs speciaux

Les operateurs *, ,, -, et / permettent d’exprimer des planifications precises sans enumerer chaque valeur.

# Toutes les 15 minutes
*/15 * * * * /usr/local/bin/heartbeat.sh

# Toutes les 5 minutes de 8h a 18h du lundi au vendredi
*/5 8-18 * * 1-5 /usr/local/bin/business_hours.sh

# A 0h00 et 12h00
0 0,12 * * * /usr/local/bin/two_per_day.sh

# A 8h, 13h et 18h
0 8,13,18 * * * /usr/local/bin/three_per_day.sh

# Toutes les 2 heures
0 */2 * * * /usr/local/bin/every_two_hours.sh

# Les weekends (samedi et dimanche)
0 10 * * 6,0 /usr/local/bin/weekend.sh
# ou
0 10 * * sat,sun /usr/local/bin/weekend.sh

Etape 4 : Raccourcis predefinis

Pour les cas courants, cron accepte des raccourcis plus lisibles que la syntaxe numerique.

@reboot   /usr/local/bin/init_au_boot.sh
@yearly   /usr/local/bin/annuel.sh       # equivaut a 0 0 1 1 *
@annually /usr/local/bin/annuel.sh       # meme chose
@monthly  /usr/local/bin/mensuel.sh      # 0 0 1 * *
@weekly   /usr/local/bin/hebdo.sh        # 0 0 * * 0
@daily    /usr/local/bin/quotidien.sh    # 0 0 * * *
@midnight /usr/local/bin/minuit.sh       # meme que @daily
@hourly   /usr/local/bin/horaire.sh      # 0 * * * *

# Exemple concret
@reboot /usr/local/bin/monter_sauvegardes.sh
@daily /usr/local/bin/backup_mysql.sh
@weekly /usr/local/bin/nettoyage_cache.sh

Etape 5 : Editer son crontab utilisateur

Chaque utilisateur a son propre crontab. Editez-le avec crontab -e. Ne jamais editer directement les fichiers dans /var/spool/cron.

# Editer MON crontab
crontab -e

# Au premier lancement, choisir l'editeur (nano recommande pour debutants)
# Puis ajouter les taches

# Lister MON crontab
crontab -l

# Supprimer MON crontab (attention, pas de confirmation)
crontab -r

# Editer le crontab d'un autre utilisateur (besoin de sudo)
sudo crontab -u deploy -e
sudo crontab -u deploy -l

# Sauvegarde avant modification
crontab -l > ~/crontab_backup_$(date +%F).txt

# Restaurer depuis fichier
crontab ~/crontab_backup_2026-04-23.txt

Etape 6 : Ecrire une premiere tache simple

Commencez par une tache qui s’execute chaque minute et ecrit dans un fichier. Cela permet de verifier que cron fonctionne dans votre environnement avant d’ajouter des operations complexes.

crontab -e
# Test minimal : ecrire la date chaque minute
* * * * * date >> /tmp/cron_test.log 2>&1
# Attendre 2-3 minutes puis verifier
cat /tmp/cron_test.log
# Thu Apr 23 14:30:01 GMT 2026
# Thu Apr 23 14:31:01 GMT 2026
# Thu Apr 23 14:32:01 GMT 2026

# Supprimer la ligne de test une fois la validation faite
crontab -e

Etape 7 : Rediriger la sortie correctement

Par defaut, cron envoie la sortie standard et les erreurs par email a l’utilisateur. Sans serveur mail, ces emails s’accumulent. Redirigez toujours vos sorties.

# Mauvais : sortie perdue ou en spam
30 2 * * * /usr/local/bin/backup.sh

# Bon : logs dans un fichier
30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Silencer completement (attention : invisible si erreur)
30 2 * * * /usr/local/bin/backup.sh > /dev/null 2>&1

# Capturer uniquement les erreurs
30 2 * * * /usr/local/bin/backup.sh > /dev/null 2>> /var/log/backup_errors.log

# Explications :
# >> fichier     : ajoute la sortie standard
# 2>&1           : redirige les erreurs vers la sortie standard (meme fichier)
# 2>> fichier    : ajoute UNIQUEMENT les erreurs

Etape 8 : Gerer les variables d’environnement

Cron execute les commandes dans un environnement minimal : PATH reduit, pas de $HOME, etc. C’est la cause #1 des scripts qui marchent en ligne de commande mais pas en cron.

# En haut du crontab, definir les variables
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/home/admin
MAILTO=admin@pme-dakar.sn    # Email pour recevoir les rapports

# Tache qui utilise ces variables
0 3 * * * /home/admin/scripts/backup.sh >> /var/log/backup.log 2>&1

# Alternative : tout definir dans le script lui-meme
# Au debut du script :
#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export HOME=/home/admin
cd /var/www/mon_app
source /home/admin/.env

Etape 9 : Cron systeme dans /etc/cron.d/

En plus des crontabs utilisateur, le systeme a des fichiers dans /etc/cron.d/, /etc/cron.daily/, /etc/cron.hourly/, /etc/cron.weekly/, /etc/cron.monthly/. Pratique pour les taches deployees par paquets.

# Creer une tache systeme
sudo nano /etc/cron.d/backup-mysql

# Syntaxe legerement differente : un champ USER avant la commande
# min  hour dom mon dow user      commande
30     2    *   *   *   admin     /usr/local/bin/backup_mysql.sh >> /var/log/backup.log 2>&1

# Permissions importantes
sudo chmod 644 /etc/cron.d/backup-mysql
sudo chown root:root /etc/cron.d/backup-mysql

# Scripts executables dans les dossiers periodiques
sudo cp nettoyage.sh /etc/cron.daily/
sudo chmod +x /etc/cron.daily/nettoyage.sh
# Attention : les noms ne doivent pas contenir de point ni d'extension

# Tester run-parts
sudo run-parts --test /etc/cron.daily/

Etape 10 : Cas concret – sauvegarde complete

Mettons en place une vraie sauvegarde nocturne : base MySQL + fichiers web + rotation sur 14 jours + notification email.

sudo nano /usr/local/bin/backup_complet.sh
#!/bin/bash
set -euo pipefail

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups"
RETENTION=14
LOG="/var/log/backup_complet.log"

exec >> "$LOG" 2>&1
echo "=== Debut sauvegarde $DATE ==="

# MySQL
mysqldump -u backup -p'PASS' --all-databases | gzip > "$BACKUP_DIR/mysql_${DATE}.sql.gz"

# Fichiers web
tar -czf "$BACKUP_DIR/www_${DATE}.tar.gz" /var/www/html

# Configs
tar -czf "$BACKUP_DIR/etc_${DATE}.tar.gz" /etc/nginx /etc/mysql

# Rotation
find "$BACKUP_DIR" -name "*.gz" -mtime +$RETENTION -delete

# Notification
TAILLE=$(du -sh "$BACKUP_DIR" | cut -f1)
echo "Sauvegarde OK. Taille totale : $TAILLE"
echo "=== Fin sauvegarde ==="
sudo chmod +x /usr/local/bin/backup_complet.sh

# Test manuel d'abord
sudo /usr/local/bin/backup_complet.sh

# Si OK, programmer
sudo crontab -e
# Tous les jours a 2h30
30 2 * * * /usr/local/bin/backup_complet.sh

Etape 11 : Deboguer un cron qui ne fonctionne pas

90% des bugs de cron viennent de l’environnement. Voici la methodologie de debug.

# 1. Verifier que cron est actif
sudo systemctl status cron

# 2. Consulter les logs de cron
grep CRON /var/log/syslog | tail -20
# ou sur certaines distrib
sudo tail -f /var/log/cron

# 3. Verifier que la tache est bien enregistree
crontab -l

# 4. Tester la commande en tant qu'utilisateur avec env minimal
env -i /bin/bash -c "/usr/local/bin/monscript.sh"

# 5. Ajouter du logging detaille dans le script
set -x
exec > /tmp/debug.log 2>&1

# 6. Simuler l'environnement cron
* * * * * env > /tmp/cron_env.txt
# Comparer avec votre env interactif : env > /tmp/shell_env.txt
diff /tmp/cron_env.txt /tmp/shell_env.txt

# 7. Verifier les permissions
ls -l /usr/local/bin/monscript.sh
# Doit etre executable

Etape 12 : Exclusion concurrente avec flock

Si une tache met plus de temps que prevu, elle peut etre lancee une deuxieme fois en parallele. flock pose un verrou qui empeche l’execution concurrente.

# Sans flock : deux instances possibles si le script prend >1 min
* * * * * /usr/local/bin/check_every_minute.sh

# Avec flock : une seule instance
* * * * * flock -n /tmp/check.lock /usr/local/bin/check_every_minute.sh

# Options flock
# -n : ne pas attendre, echouer immediatement si verrou pris
# -w 10 : attendre 10 secondes max pour le verrou
# -x : verrou exclusif (defaut)

# Exemple reel : sync toutes les 5 minutes mais sans recouvrement
*/5 * * * * flock -n /tmp/sync.lock /usr/local/bin/sync_stock.sh >> /var/log/sync.log 2>&1

# Verifier qu'un verrou est bien liberé apres execution
lsof /tmp/sync.lock

Etape 13 : Alternative moderne – systemd timers

Sur les systemes modernes, systemd timers offrent des avantages : logs integres via journalctl, dependances entre services, et catch-up (execution si le serveur etait eteint).

# Creer le service
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Sauvegarde MySQL quotidienne
After=network.target mysql.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup_mysql.sh
User=admin
Group=admin
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Declenche la sauvegarde chaque jour a 2h30

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target
# Activer et demarrer
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer

# Verifier
sudo systemctl list-timers
# Voir la prochaine execution

# Logs
sudo journalctl -u backup.service -f

# Declencher manuellement
sudo systemctl start backup.service

# Desactiver
sudo systemctl disable backup.timer

Etape 14 : Bonnes pratiques production

Quelques regles pour que vos crons restent fiables dans la duree.

# 1. Toujours chemins absolus
# Mauvais
0 2 * * * cd /var/www && ./backup.sh
# Bon
0 2 * * * /usr/local/bin/backup_www.sh

# 2. Script qui change de dossier en interne
#!/bin/bash
cd /var/www || exit 1
tar -czf /backups/www.tar.gz .

# 3. Tester l'execution en cron manuellement
at now + 1 minute -f /usr/local/bin/backup.sh

# 4. Documenter le crontab
# Ajouter des commentaires expliquant chaque ligne
# ===================================
# BACKUPS
# ===================================
30 2 * * *   /usr/local/bin/backup_mysql.sh
30 3 * * *   /usr/local/bin/backup_www.sh
0  4 * * 0   /usr/local/bin/backup_hebdo.sh

# ===================================
# MAINTENANCE
# ===================================
0  5 * * *   /usr/local/bin/rotate_logs.sh
*/10 * * * * /usr/local/bin/monitor.sh

# 5. Monitoring des crons : envoyer un ping vers une URL externe
# Services comme healthchecks.io ou cronitor.io
0 2 * * * /usr/local/bin/backup.sh && curl -fsS https://hc-ping.com/UUID

Erreurs

Chemins relatifs dans les commandes : cron ne s’execute pas dans votre repertoire courant. Utilisez toujours des chemins absolus ou un cd explicite en debut de script.

PATH incomplet : cron demarre avec un PATH minimal. Des commandes comme mysqldump ou aws peuvent etre introuvables. Definissez PATH en haut du crontab ou utilisez les chemins complets /usr/bin/mysqldump.

Oublier la redirection des erreurs : sans 2>&1, vous ne verrez pas pourquoi une tache echoue. Redirigez systematiquement la sortie ET les erreurs vers un fichier log.

Executer plusieurs instances simultanees : un script de sync qui met 10 minutes planifie toutes les 5 minutes va s’empiler. Utilisez flock pour garantir une seule instance a la fois.

Tester uniquement en interactif : le script marche quand vous le lancez, mais pas en cron. Testez avec env -i bash -c "/chemin/script.sh" pour simuler l’environnement cron reduit.

Jour de la semaine et jour du mois conflit : si vous mettez 0 0 15 * 1, cron declenche le 15 du mois OU le lundi (OR, pas AND). Pour une vraie combinaison, filtrez dans le script.

Crontab plein de taches silencieuses : au bout d’un an, personne ne sait ce qu’elles font. Documentez chaque ligne avec un commentaire et centralisez la liste dans Git.

Checklist

Service cron actif et active au demarrage (systemctl enable cron).

Syntaxe crontab maitrisee : minute, heure, jour_mois, mois, jour_semaine.

Chemins absolus utilises dans toutes les commandes.

Variables PATH et SHELL definies en haut du crontab.

Sortie et erreurs redirigees avec >> log 2>&1.

Scripts testes manuellement avant planification.

Scripts testes en environnement minimal env -i bash -c.

flock utilise pour empecher les executions concurrentes.

Rotation des logs configuree (logrotate).

Rotation des sauvegardes incluse dans le script (find -mtime -delete).

Chaque ligne du crontab documentee par un commentaire.

Sauvegarde du crontab versionnee dans Git.

Monitoring externe type healthchecks.io pour etre alerte en cas d’echec.

Logs consultes regulierement : grep CRON /var/log/syslog.

Systemd timers consideres pour les cas complexes (dependances, catch-up).

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité