systemd timers : remplacer cron proprement
À la fin de ce tutoriel, vous saurez créer un couple
.timer+.service, exprimer un calendrier avecOnCalendar, activerPersistent=trueetRandomizedDelaySec, pilotersystemctl list-timers/enable --now, et remplacer un cron DevOps (healthcheck ou backup lab) — de préférence en systemd user (~/.config/systemd/user/). Focus systemd timer : ce n’est pas une copie du bonus systemd avancé (units/journal en largeur) ni un redo du service hello de processus & systemd.Niveau : Intermédiaire · Temps estimé : 45–55 min · Versions testées : Ubuntu 22.04 / 24.04, Debian 12 ; notes Rocky/Alma 9 · Dernière vérification : 2026-09-11
Slug proposé :
linux-systemd-timers· Série : Linux Shell & Automation · Remplace / fusionne : N/A — création (chapitre 4, fin lot 1)
Prérequis
- Hub Linux Shell & Automation ; awk pratique (scripts de rapport utiles dans ExecStart)
- Processus & systemd (
systemctl, daemon-reload) ; pont bonus systemd avancé (aperçu timers / journal) — on approfondit la planification ici - Session utilisateur avec bus systemd (
systemctl --user status) ; sinonloginctl enable-linger "$USER"en lab, ou variante system avec sudo - Scripts sans secrets sous
/tmp/lab-timers; console inutile sauf si vous touchez des units system
Coût : 0 €. Lab user = pas besoin de root pour le cœur.
Ce que nous allons construire
Pourquoi timer vs cron (cas DevOps)
→ Anatomie : .service oneshot + .timer OnCalendar
→ Persistent= · RandomizedDelaySec=
→ list-timers · enable --now · status · journalctl --user -u
→ Lab healthcheck (curl) + variante backup tar
→ Nettoyage complet
(Schéma à remplacer par une image locale Excalidraw / draw.io, alt : « systemd timer : OnCalendar, Persistent, RandomizedDelaySec, list-timers, service oneshot ».)
Dernier chapitre lot 1 Shell & Automation. Après bash/grep/awk, on planifie proprement : logs unifiés, dépendances d’units, rattrapage après downtime (Persistent=). Un healthcheck toutes les minutes convient au lab ; en production, préférez hourly / daily et surveillez list-timers + alertes sur échec du service.
Étape 1 — Timer vs cron : quand migrer
| Besoin | cron | systemd timer |
|---|---|---|
| Hôte avec systemd | OK | Natif, journalctl -u |
| Rattraper un run manqué (machine éteinte) | Limité | Persistent=true |
| Aléatoiriser la charge (flotte) | Astuces shell | RandomizedDelaySec= |
| Droits user sans crontab | crontab -u |
Units user propres |
| Documentation Git | Fichier cron | Fichiers .timer/.service versionnables |
Le bonus P5 montre déjà un timer minimal. Ici : calendriers utiles, options anti-thundering-herd, lab healthcheck/backup, debug list-timers.
# Bus user OK ?
systemctl --user status | head -n 5
# Timers déjà présents (lecture)
systemctl --user list-timers --all 2>/dev/null | head
systemctl list-timers --all 2>/dev/null | head
Étape 2 — Anatomie : service oneshot + timer
Le timer ne contient pas la charge utile : il active un service du même nom (par défaut foo.timer → foo.service).
mkdir -p /tmp/lab-timers "$HOME/.config/systemd/user"
# Charge utile : healthcheck lab (pas de secret)
cat > /tmp/lab-timers/healthcheck.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
stamp=$(date -Is)
# Cible locale sûre ; remplacez par votre URL lab si besoin
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://127.0.0.1/ || echo 000)
echo "$stamp health code=$code" >> /tmp/lab-timers/health.log
EOF
chmod +x /tmp/lab-timers/healthcheck.sh
# Service : Type=oneshot (tâche qui se termine)
cat > "$HOME/.config/systemd/user/lab-health.service" << 'EOF'
[Unit]
Description=Lab healthcheck Shell Automation (timer)
After=network-online.target
[Service]
Type=oneshot
ExecStart=/tmp/lab-timers/healthcheck.sh
EOF
| Directive service | Rôle timer-lab |
|---|---|
Type=oneshot |
Script court (backup, check) |
ExecStart= |
Chemin absolu du script |
After= |
Optionnel : attendre le réseau |
On ne refait pas toute la zoologie Restart= / User= du bonus P5 : le service sert le timer.
Étape 3 — OnCalendar, Persistent, RandomizedDelaySec
cat > "$HOME/.config/systemd/user/lab-health.timer" << 'EOF'
[Unit]
Description=Timer lab healthcheck toutes les minutes (lab)
[Timer]
# Calendrier : chaque minute (lab agressif — en prod : hourly / daily)
OnCalendar=*-*-* *:*:00
Persistent=true
RandomizedDelaySec=10
Unit=lab-health.service
[Install]
WantedBy=timers.target
EOF
# Valider la calendrier expression
systemd-analyze calendar '*-*-* *:*:00'
systemd-analyze calendar 'Mon *-*-* 03:30:00'
systemd-analyze calendar hourly
| Directive timer | Effet |
|---|---|
OnCalendar= |
Expression type calendrier (voir systemd.time) |
Persistent=true |
Si l’échéance a été manquée (down), run au prochain boot/dispo |
RandomizedDelaySec= |
Délai aléatoire 0…N s (évite que 50 VPS tapent l’API en même temps) |
OnBootSec= / OnUnitActiveSec= |
Alternatives monotones (intervalles) |
Unit= |
Service à activer (défaut = même préfixe) |
Exemples OnCalendar utiles : hourly, daily, weekly, *-*-* 04:00:00, Mon *-*-* 03:30:00. Vérifiez toujours avec systemd-analyze calendar. Attention au fuseau : les expressions sont interprétées dans le timezone système (timedatectl) — un « 04:00 » UTC ≠ 04:00 Europe/Paris.
Étape 4 — Activer, lister, journal
systemctl --user daemon-reload
systemctl --user enable --now lab-health.timer
systemctl --user status lab-health.timer --no-pager
systemctl --user list-timers --all | grep -E 'lab-health|NEXT|PASS' || systemctl --user list-timers --all | head
# Déclencher immédiatement (sans attendre la minute)
systemctl --user start lab-health.service
tail -n 5 /tmp/lab-timers/health.log
# Logs du service déclenché par le timer
journalctl --user -u lab-health.service -n 20 --no-pager
| Commande | Rôle |
|---|---|
enable --now *.timer |
Active au login/boot user et démarre |
list-timers |
Prochain / dernier run |
start *.service |
Run manuel de la charge utile |
journalctl --user -u … |
Sortie capturée si besoin ; ici aussi append fichier |
Si Failed to connect to bus : reconnectez une session graphique/ssh avec systemd user, ou loginctl enable-linger "$USER" en lab.
Étape 5 — Variante backup + note system units
# Backup lab : tar d’un dossier jetable
mkdir -p /tmp/lab-timers/data /tmp/lab-timers/backup
echo "payload $(date -Is)" > /tmp/lab-timers/data/file.txt
cat > /tmp/lab-timers/backup.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
stamp=$(date +%Y%m%d-%H%M%S)
tar -C /tmp/lab-timers -czf "/tmp/lab-timers/backup/data-$stamp.tgz" data
echo "$(date -Is) backup data-$stamp.tgz" >> /tmp/lab-timers/backup.log
# Rétention lab : garder 3 archives
ls -1t /tmp/lab-timers/backup/data-*.tgz 2>/dev/null | tail -n +4 | xargs -r rm -f
EOF
chmod +x /tmp/lab-timers/backup.sh
cat > "$HOME/.config/systemd/user/lab-backup.service" << 'EOF'
[Unit]
Description=Lab backup tar (timer)
[Service]
Type=oneshot
ExecStart=/tmp/lab-timers/backup.sh
EOF
cat > "$HOME/.config/systemd/user/lab-backup.timer" << 'EOF'
[Unit]
Description=Timer lab backup horaire
[Timer]
OnCalendar=hourly
Persistent=true
RandomizedDelaySec=120
AccuracySec=1min
[Install]
WantedBy=timers.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now lab-backup.timer
systemctl --user start lab-backup.service
ls -la /tmp/lab-timers/backup/
Variante system (VM lab root) — seulement si le user bus est indisponible :
# sudo cp ~/.config/systemd/user/lab-health.* /etc/systemd/system/
# sudo systemctl daemon-reload
# sudo systemctl enable --now lab-health.timer
# Nettoyage : disable --now + rm + daemon-reload
Préférez user pour ce lot : moins de risque, aligné scripts /tmp.
Étape 6 — Vérification et nettoyage (fin lot 1)
systemctl --user list-timers | grep lab- || true
systemctl --user is-enabled lab-health.timer lab-backup.timer 2>/dev/null || true
# Nettoyage timers lab
systemctl --user disable --now lab-health.timer lab-backup.timer 2>/dev/null || true
systemctl --user stop lab-health.service lab-backup.service 2>/dev/null || true
rm -f "$HOME/.config/systemd/user/lab-health.service"
"$HOME/.config/systemd/user/lab-health.timer"
"$HOME/.config/systemd/user/lab-backup.service"
"$HOME/.config/systemd/user/lab-backup.timer"
systemctl --user daemon-reload
rm -rf /tmp/lab-timers
systemctl --user list-timers | grep lab- || echo "lab timers nettoyés — OK"
echo "Fin lot1 Shell & Automation → hub /tutoriels/linux-shell-automation/"
Validé si : OnCalendar validé via systemd-analyze calendar, list-timers montre NEXT/LAST, Persistent / RandomizedDelaySec présents dans le .timer, healthcheck ou backup a écrit un log, nettoyage sans units orphelines. Vous avez bouclé le lot 1 : scripts robustes → recherche → agrégats → planification.
Erreurs fréquentes
| Symptôme | Cause | Correction |
|---|---|---|
| Timer enabled mais jamais de run | Mauvais OnCalendar / fuseau |
systemd-analyze calendar ; list-timers |
Failed to connect to bus |
Session user absente | linger / re-login / units system en lab |
| Service OK en manuel, timer non | Timer non enable --now |
enable --now lab-xxx.timer |
| Pas de rattrapage après down | Persistent oublié |
Persistent=true |
| Tous les hôtes tapent en même temps | Pas de random delay | RandomizedDelaySec= |
| Refaire un long unit Type=simple | Confusion bonus P5 | Ici oneshot + timer |
| Scripts relatifs dans ExecStart | cwd flou | Chemins absolus |
Quiz (3 questions)
1. Rôle principal d’un fichier .timer ?
– A. Remplacer le noyau
– B. Déclencher un .service selon un calendrier / intervalle
– C. Compiler awk
2. À quoi sert Persistent=true ?
– A. Garder le laptop allumé
– B. Exécuter les échéances manquées quand la machine revient
– C. Désactiver journalctl
3. Pourquoi RandomizedDelaySec sur une flotte ?
– A. Pour chiffrer les logs
– B. Pour étaler la charge et éviter un pic synchronisé
– C. Pour remplacer AllowUsers
Réponses : 1‑B · 2‑B · 3‑B
FAQ
Faut-il supprimer cron partout ?
Non. cron reste répandu. Migrez les tâches machine où vous voulez journalctl, dépendances d’units et Persistent=. Les crons multi-user ad hoc peuvent rester tant qu’ils sont documentés.
Lien avec le bonus systemd-avance ?
Le bonus P5 introduit units + journal + un timer. Ce chapitre spécialise timers (OnCalendar, Persistent, RandomizedDelaySec, labs healthcheck/backup, list-timers). Lisez le bonus en pont, ne le recopiez pas.
Timer user vs system ?
User : tâches de votre compte (labs, backups $HOME). System : tâches machine (root, /etc). Pour la flotte serveurs, system + user dédié de service est courant.
Pour aller plus loin
man systemd.timer,man systemd.time,man systemd-analyze- Pont P5 : systemd avancé · processus & systemd
- Fin lot 1 : hub Linux Shell & Automation · Admin cron (quand publié) pour comparer
Maillage série Linux Shell & Automation
| ← Précédent | awk pratique : colonnes, agrégats et rapports |
| → Suivant | Hub Linux Shell & Automation (fin lot 1) |
| Pont P5 | systemd avancé · processus & systemd |
| Hub | Linux Shell & Automation |
Meta publication (à remplir dans Rank Math / SEO)
- Title SEO : systemd timers : OnCalendar à la place de cron (2026)
- Meta description (≤ 155) : Créez des timers systemd (OnCalendar, Persistent) pour remplacer cron. Suite Shell Automation DevOps 2026.
- Focus keyphrase : systemd timer
- KW secondaires : OnCalendar, Persistent=true, RandomizedDelaySec, list-timers
- Schemas Rank Math : Article + HowTo (étapes lab) + FAQ (3 questions ci-dessus)
- Image mise en avant :
assets/web/devopelastichayway/cover-linux-systemd-timers-1200x630.webp(Visuels Linux — WebP 1200×630) - Catégorie : Linux · Niveau : Intermédiaire
- Slug :
linux-systemd-timers - Statut : HOLD — draft only (ne pas publier)
← Retour parcours Linux — Basics, Admin, Réseau & Sécurité, Shell & Automation.