Cours Linux / Planifier des tâches avec cron et les timers systemd
Pour une tâche simple planifiée par heure, cron peut suffire ; pour suivre une tâche comme service avec son état et ses journaux, utilisez un timer systemd lorsque le gestionnaire d’utilisateur est disponible. Une ligne enregistrée ou un timer activé ne prouve pas que le travail a réussi : vérifiez l’heure prévue, l’exécution réelle, le résultat et les cas où la machine ou la session étaient arrêtées.
Exécutez d’abord la commande seule, comme dans le premier script Bash, avant de la planifier. Cet atelier concerne une machine virtuelle Ubuntu 26.04 LTS ou Rocky Linux 9 avec gestionnaire systemd --user. Une distribution minimale, un conteneur ou WSL peut avoir un environnement différent ; le cours de préparation de la machine virtuelle aide à prévoir la console et les contrôles de version.
Choisir entre cron et un timer systemd
| Critère | cron | Timer systemd |
|---|---|---|
| Configuration | Une expression horaire et une commande dans la crontab. | Une unité .timer et un service à déclencher. |
| Résultat | Sortie de la tâche et journaux, selon la distribution et sa configuration. | État du service, résultat et journal associés. |
| Environnement | Environnement de crontab, distinct du terminal interactif. | Environnement défini par le gestionnaire et l’unité. |
| Séance manquée | Un cron classique ne rejoue normalement pas toutes les heures manquées ; des outils distincts peuvent compléter ce comportement. | Persistent=true peut rattraper une activation de calendrier après l’arrêt du timer, sous conditions. |
La disponibilité et le nom du service cron dépendent de la distribution : Ubuntu utilise souvent le paquet cron, Rocky Linux le paquet cronie et le démon crond. Un timer utilisateur exige un gestionnaire systemd utilisateur actif. Le choix dépend aussi des droits de la tâche, du besoin de traces et de la durée de vie de la session.
Lire une expression cron avant de l’installer
crontab -e édite la crontab de l’utilisateur courant, si un service cron est installé et en fonction. Une entrée utilisateur contient cinq champs horaires — minute, heure, jour du mois, mois, jour de la semaine — puis la commande. L’exemple suivant décrit une exécution quotidienne à 02 h 15 dans la zone horaire du démon. Remplacez USER par le vrai chemin de votre compte et testez le script séparément avant d’ajouter la ligne :
15 2 * * * /bin/bash /home/USER/bin/job.sh >> /home/USER/job.log 2>&1
Ce n’est pas une commande à coller telle quelle dans le terminal : il faut l’insérer dans la crontab au moyen de crontab -e, puis confirmer avec crontab -l. /etc/crontab a un champ utilisateur supplémentaire et ne reprend pas exactement ce format. Évitez les chemins relatifs et les hypothèses sur PATH ou le répertoire courant. Dans Cronie, les champs jour du mois et jour de la semaine restreints ensemble ont une logique d’alternative susceptible de surprendre ; les changements d’heure et le caractère % ont aussi des règles particulières. Le manuel officiel Cronie de crontab les décrit. Une autre implémentation de cron peut différer : consultez celle installée.
Ne mettez pas de secret directement dans la ligne de crontab. Prévoyez un chemin de journal et une politique de conservation, puis vérifiez la sortie et les échecs réels de la tâche. L’existence de la ligne n’établit pas que le démon a pu lancer la commande.
Préparer un service et un timer utilisateur sans écraser d’unité
Vérifiez d’abord systemctl --user status et command -v date. Si le gestionnaire utilisateur est indisponible, arrêtez cet atelier au lieu de créer des unités inactives. Choisissez les noms ci-dessous seulement si aucun fichier de même nom n’existe déjà. Les commandes créent deux fichiers dans votre configuration utilisateur ; elles ne demandent pas de privilège administrateur. Le service lance simplement date dans le journal, sans modifier de données de production.
unit_dir="$HOME/.config/systemd/user"
service="$unit_dir/linux-course-clock-fr.service"
timer="$unit_dir/linux-course-clock-fr.timer"
date_bin=$(command -v date)
test -n "$date_bin" && test "${date_bin#/}" != "$date_bin" &&
test ! -e "$service" && test ! -L "$service" &&
test ! -e "$timer" && test ! -L "$timer" &&
mkdir -p -- "$unit_dir"
Le dernier contrôle ne doit produire aucune erreur. Si un nom existe déjà, choisissez un autre nom cohérent pour les deux unités et toutes les commandes suivantes ; ne retirez pas l’unité préexistante. La vérification préalable ne protège pas contre une modification concurrente dans un dossier partagé : utilisez votre configuration utilisateur personnelle.
Créez maintenant les deux unités dans le même terminal afin que service, timer et date_bin gardent leur valeur. La première unité a Type=oneshot : elle lance la commande puis se termine. La seconde demande une activation à chaque début de minute. Vérifiez visuellement les deux fichiers avant de les activer.
if [[ -e "$service" || -L "$service" || -e "$timer" || -L "$timer" ]]; then
printf 'Un nom d’unité existe déjà : ne rien écraser\n' >&2
false
else
cat > "$service" <<EOF
[Unit]
Description=Horloge de pratique du cours Linux
[Service]
Type=oneshot
ExecStart=$date_bin
EOF
cat > "$timer" <<'EOF'
[Unit]
Description=Lancer l’horloge de pratique chaque minute
[Timer]
OnCalendar=*-*-* *:*:00
AccuracySec=1s
Persistent=true
[Install]
WantedBy=timers.target
EOF
cat -- "$service" "$timer"
fi
Le chemin de date est inséré comme chemin absolu découvert sur la machine ; si votre environnement utilise un fournisseur différent pour cet outil, l’exercice conserve le fournisseur déjà présent. Le nom du timer active normalement le service du même nom de base. AccuracySec=1s limite la fenêtre de regroupement demandée sans promettre un déclenchement en temps réel. Persistent=true peut déclencher une fois une séance de calendrier manquée lorsque le timer redevient actif ; il ne rejoue pas nécessairement chaque minute écoulée. Le manuel officiel de systemd.timer expose ces conditions.
Valider le calendrier, activer et observer le résultat
Demandez d’abord à systemd d’interpréter le calendrier ; contrôlez que les prochains horaires correspondent à votre intention et à la zone horaire de la machine. Rechargez ensuite les unités utilisateur et activez le timer. Si une commande échoue, lisez son diagnostic avant de continuer ; ne considérez pas une activation partielle comme une installation réussie.
systemd-analyze calendar '*-*-* *:*:00'
systemctl --user daemon-reload
systemctl --user enable --now linux-course-clock-fr.timer
systemctl --user list-timers --all linux-course-clock-fr.timer
systemctl --user status linux-course-clock-fr.timer
Le manuel des expressions de temps systemd détaille les horaires. La liste doit afficher une prochaine activation. Après une ou deux minutes, vérifiez le journal du service et son état de résultat. Un service oneshot qui s’est terminé peut être inactive tout en ayant réussi ; regardez Result, ExecMainStatus et les messages au lieu d’interpréter ce seul mot.
journalctl --user -u linux-course-clock-fr.service --since '5 minutes ago' --no-pager
systemctl --user show linux-course-clock-fr.service -p Result -p ExecMainStatus
timedatectl
timedatectl aide à lire la zone horaire et l’état de l’horloge. Si vous attendez une exécution après déconnexion, contrôlez la durée de vie du gestionnaire utilisateur et la politique linger de cette VM ; activer un timer utilisateur ne prouve pas à lui seul qu’il fonctionnera après chaque déconnexion ou redémarrage. Pour un travail de production, prévoyez aussi une détection des séances jamais exécutées, pas seulement des erreurs des séances lancées.
Éviter les chevauchements et retirer uniquement l’exercice
Un travail cron plus long que son intervalle peut se chevaucher avec son lancement suivant ; un verrou adapté, par exemple via flock si disponible, et le traitement d’un verrou abandonné doivent être étudiés. Un timer systemd n’engendre pas une nouvelle instance du même service déjà actif au moment du déclenchement, mais d’autres unités ou un lancement manuel peuvent utiliser les mêmes ressources. La tâche elle-même doit définir son comportement face à la concurrence.
Pour terminer la pratique, désactivez et arrêtez d’abord le timer. Avant chaque suppression, contrôlez que les chemins désignent bien les deux fichiers que vous venez de créer et que vous êtes dans le même compte utilisateur. Puis retirez exactement ces deux fichiers et rechargez le gestionnaire. Si la création s’était arrêtée après un seul fichier, adaptez la suppression au fichier réellement présent.
systemctl --user disable --now linux-course-clock-fr.timer
unit_dir="$HOME/.config/systemd/user"
service="$unit_dir/linux-course-clock-fr.service"
timer="$unit_dir/linux-course-clock-fr.timer"
ls -l -- "$service" "$timer"
rm -- "$timer" "$service"
systemctl --user daemon-reload
systemctl --user list-timers --all linux-course-clock-fr.timer
Une entrée cron ajoutée pour un autre essai doit être retirée par crontab -e en supprimant seulement cette ligne, puis contrôlée avec crontab -l. Ne remplacez pas cette opération par l’effacement de toute la crontab. La vérification de désactivation porte sur le timer de l’exercice ; elle ne prouve pas qu’un autre mécanisme planifié n’exécute pas une commande semblable.




