systemd (Français)/Timers (Français)
Les «timers» (minuteurs) sont des fichiers d'unité systemd dont le nom se termine par .timer et qui contrôlent des fichiers ou des événements .service. Les timers peuvent être utilisés comme une alternative à cron. (lire #En tant que remplacement de cron). Les timers prennent en charge par défaut les événements du calendrier, les événements monotones, et peuvent être exécutés de manière asynchrone.
Unités timer
Les «timers» sont des fichiers d'unités systemd avec un suffixe .timer. Les timers sont comme les autres fichiers de configuration d'unité et sont chargés à partir des mêmes chemins mais incluent une section [Timer]
qui définit quand et comment le timer s'active. Les timers sont définis comme l'un des deux types suivants :
- Les timers en temps réel (aussi appelés timers d'«horloge murale») sont activés par un événement du calendrier, de la même manière que les tâches de cron. L'option
OnCalendar=
est utilisée pour les définir. - Les timers monotoniques s'activent après un laps de temps relatif à un point de départ variable. Ils s'arrêtent si l'ordinateur est temporairement suspendu ou éteint. Il existe un certain nombre de timers monotones différents mais tous ont la forme suivante :
OnTypeSec=
. Les timers monotones courants comprennentOnBootSec
etOnUnitActiveSec
.
Pour une explication complète des options des timers, consultez systemd.timer(5). La syntaxe des arguments pour les événements du calendrier et les intervalles de temps est définie dans systemd.time(7).
timers.target
qui configure tous les timers qui doivent être actifs après le démarrage (consultez systemd.special(7) pour plus de détails). Pour l'utiliser, ajoutez WantedBy=timers.target
à la section [Install]
de votre timer et activez l'unité timer.Unités service
Pour chaque fichier ".timer", il existe un fichier ".service" correspondant (par exemple, truc.timer
et truc.service
). Le fichier timer active et contrôle le fichier service. Le service ne nécessite pas de section [Install]
car ce sont les unités timer qui sont activées. Si nécessaire, il est possible de contrôler une unité portant un nom différent en utilisant l'option Unit=
dans la section [Timer]
du timer.
Gestion
Pour utiliser une unité timer activez et démarrez-la comme toute autre unité (n'oubliez pas d'ajouter le suffixe .timer). Pour voir tous les timers démarrés, exécutez :
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service
- Pour lister tous les timers (y compris les inactifs), utilisez
systemctl list-timers --all
. - L'état d'un service démarré par un timer sera probablement inactif, sauf s'il est en cours de déclenchement.
- Si un timer s'est désynchronisé, il peut être utile de supprimer son fichier
stamp-*
dans/var/lib/systemd/timers
. (ou~/.local/share/systemd/
dans le cas de timers utilisateur). Ce sont des fichiers de longueur nulle qui marquent la dernière fois que chaque minuterie a été exécutée. S'ils sont supprimés, ils seront reconstruits au prochain démarrage de leur timer.
Exemples
Un fichier d'unité de service peut être planifié avec un timer par défaut. Les exemples suivants planifient l'exécution de truc.service
avec un temporisateur correspondant appelé truc.timer
.
Minuterie monotone
Une minuterie qui démarre 15 minutes après le démarrage et qui recommence toutes les semaines pendant que le système fonctionne.
/etc/systemd/system/truc.timer
[Unit] Description=Exécuter truc chaque semaine et au démarrage [Timer] OnBootSec=15min OnUnitActiveSec=1w [Install] WantedBy=timers.target
Minuterie en temps réel
Une minuterie qui se déclenche une fois par semaine (à 12h00 le lundi). Lorsqu'il est activé, il déclenche le service immédiatement s'il a manqué la dernière heure de démarrage (option Persistent=true
), par exemple en raison de la mise hors tension du système :
/etc/systemd/system/truc.timer
[Unit] Description=Exécuter truc chaque semaine [Timer] OnCalendar=weekly Persistent=true [Install] WantedBy=timers.target
Lorsque des dates et des heures plus spécifiques sont requises, les événements OnCalendar
utilisent le format suivant :
DayOfWeek Year-Month-Day Hour:Minute:Second
Un astérisque peut être utilisé pour spécifier n'importe quelle valeur et des virgules peuvent être utilisées pour énumérer les valeurs possibles. Deux valeurs séparées par ..
indiquent une plage contiguë.
Dans l'exemple ci-dessous, le service est lancé les quatre premiers jours de chaque mois à 12h00, mais seulement si ce jour est un lundi ou un mardi.
OnCalendar=Mon,Tue *-*-01..04 12:00:00
Pour lancer un service le premier samedi de chaque mois, utilisez :
OnCalendar=Sat *-*-1..7 18:00:00
Lorsque vous utilisez la partie DayOfWeek
, vous devez spécifier au moins un jour de la semaine. Si vous voulez que quelque chose s'exécute tous les jours à 4 heures du matin, utilisez :
OnCalendar=*-*-* 4:00:00
Pour exécuter un service à différents moments, OnCalendar
peut être spécifié plusieurs fois. Dans l'exemple ci-dessous, le service fonctionne à 22h30 les jours de semaine et à 20h00 le week-end.
OnCalendar=Mon..Fri 22:30 OnCalendar=Sat,Sun 20:00
De plus amples informations sont disponibles dans systemd.time(7).
- Les spécifications temporelles de
OnCalendar
peuvent être testées afin de vérifier leur validité et de calculer le temps suivant où la condition s'écoulera lorsqu'elles sont utilisées sur un fichier d'unité de temporisation avec l'optioncalendar
de l'utilitaire systemd-analyze. Par exemple, on peut utilisersystemd-analyze calendar weekly
ousystemd-analyze calendar "Mon,Tue *-*-01..04 12:00:00"
. - La commande
faketime
est particulièrement utile pour tester divers scénarios avec la commande ci-dessus ; elle est fournie avec le paquetlibfaketime. - Les expressions d'événements spéciaux comme
daily
etweekly
font référence à des heures de début spécifiques et, par conséquent, toutes les minuteries partageant ces événements de calendrier démarreront simultanément. Les minuteries partageant des événements de démarrage peuvent entraîner une baisse des performances du système si les services des minuteries sont en concurrence pour les ressources du système. L'optionRandomizedDelaySec
de la section[Timer]
évite ce problème en décalant de manière aléatoire l'heure de démarrage de chaque minuterie. Consultez systemd.timer(5). - Ajouter l'option
AccuracySec=1us
à la section[Timer]
, pour éviter l'imprécision de la valeur par défaut deAccuracySec
de 1m. Consultez également systemd.timer(5).
Unités transitoires timer
On peut utiliser systemd-run
pour créer des unités transitoires .timer. C'est-à-dire que l'on peut configurer une commande pour qu'elle s'exécute à un moment précis sans avoir de fichier de service. Par exemple, la commande suivante touche un fichier après 30 secondes :
# systemd-run --on-active=30 /bin/touch /tmp/truc
On peut également spécifier un fichier de service préexistant qui n'a pas de fichier de temporisation. Par exemple, la commande suivante démarre l'unité systemd nommée unitequelconque.service
après que 12,5 heures se soient écoulées :
# systemd-run --on-active="12h 30m" --unit unitequelconque.service
Consultez systemd-run(1) pour plus d'informations et d'exemples.
En tant que remplacement de cron
Bien que cron soit sans doute le planificateur de tâches le plus connu, les minuteries systemd peuvent être une alternative.
Avantages
Les principaux avantages de l'utilisation des timers proviennent du fait que chaque tâche a son propre service systemd. Certains de ces avantages sont :
- Les tâches peuvent être facilement lancées indépendamment de leurs timers. Cela simplifie le débogage.
- Chaque tâche peut être configurée pour s'exécuter dans un environnement spécifique (consultez systemd.exec(5)).
- Les tâches peuvent être attachées à des cgroups.
- Les tâches peuvent être configurées pour dépendre d'autres unités systemd.
- Les tâches sont enregistrées dans le journal systemd pour faciliter le débogage.
Avertissements
Certaines choses qui sont faciles à faire avec cron sont difficiles à faire avec les unités de temporisation seules :
- Création : pour configurer une tâche minutée avec systemd, vous devez créer deux fichiers et exécuter des commandes
systemctl
, alors qu'il suffit d'ajouter une simple ligne à une crontab. - Courriers électroniques : il n'y a pas d'équivalent intégré à
MAILTO
de cron pour l'envoi de courriers électroniques en cas d'échec de la tâche. Consultez la section suivante pour un exemple de mise en place d'une fonctionnalité similaire en utilisantOnFailure=
.
Notez également que les minuteries de l'utilisateur ne s'exécutent par défaut que lorsqu'une session de connexion de l'utilisateur est active. Cependant, la persistance peut permettre aux services de s'exécuter au démarrage même lorsque l'utilisateur n'a pas de session de connexion active.
MAILTO
Vous pouvez configurer systemd pour qu'il envoie un courrier électronique lorsqu'une unité échoue. Cron envoie un courrier à MAILTO
si la tâche affiche du contenu sur stdout ou stderr, mais de nombreuses tâches sont configurés pour n'afficher qu'en cas d'erreur. Vous avez d'abord besoin de deux fichiers : un exécutable pour envoyer le courrier et un .service pour démarrer l'exécutable. Pour cet exemple, l'exécutable est juste un script shell utilisant sendmail
, qui se trouve dans les paquets qui fournissent smtp-forwarder
.
/usr/local/bin/systemd-email
#!/bin/sh /usr/bin/sendmail -t <<ERRMAIL To: $1 From: systemd <root@$HOSTNAME> Subject: $2 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 $(systemctl status --full "$2") ERRMAIL
Quel que soit l'exécutable que vous utilisez, il devrait probablement accepter au moins deux arguments comme le fait ce script shell : l'adresse à laquelle envoyer et le fichier de l'unité dont il faut obtenir l'état. Le .service que nous créons passera ces arguments :
/etc/systemd/system/status_email_user@.service
[Unit] Description=Courriel d'état pour %i à utilisateur. [Service] Type=lancement unique ExecStart=/usr/local/bin/systemd-email adresse %i User=nobody Group=systemd-journal
Où user
est l'utilisateur qui reçoit le courriel et address
est l'adresse courriel de cet utilisateur. Bien que le destinataire soit codé en dur, le fichier de l'unité à rapporter est transmis comme paramètre d'instance, de sorte que ce service unique peut envoyer des courriels pour de nombreuses autres unités. À ce stade, démarrez status_email_user@dbus.service
pour vérifier que vous pouvez recevoir les courriels.
Ensuite, éditez simplement le service pour lequel vous voulez recevoir des courriels et ajoutez OnFailure=status_email_user@%n.service
à la section [Unit]
. %n
transmet le nom de l'unité au modèle.
- Si vous configurez la sécurité sSMTP conformément à sSMTP#Security, l'utilisateur
nobody
n'aura pas accès à/etc/ssmtp/ssmtp.conf
, et la commandesystemctl start status_email_user@dbus.service
échouera. Une solution consiste à utiliserroot
comme utilisateur dans l'unitéstatus_email_user@.service
. - Si vous essayez d'utiliser
mail -s somelogs address
dans votre script de courriel,mail
va forker et systemd va tuer le processus de courriel lorsqu'il consultera votre script. Évitez ce comportement en faisantmail -Ssendwait -s somelogs address
.
Utilisation d'une crontab
Plusieurs de ces problèmes peuvent être contournés en installant un paquet qui analyse une crontab traditionnelle pour configurer les timers. systemd-cron-nextAUR et systemd-cronAUR sont deux de ces paquets. Ils peuvent fournir la fonctionnalité MAILTO
manquante.
De plus, comme avec les crontabs, une vue unifiée de tous les travaux planifiés peut être obtenue avec systemctl
. Consultez #Gestion.
Voir aussi
- systemd.timer(5)
- Fedora:Features/SystemdCalendarTimers
- Gentoo:Systemd#Timer services
- systemd-cron-next — outil pour générer des minuteries/services à partir des fichiers crontab et anacrontab
- systemd-cron — provides systemd units to run cron scripts ; using systemd-crontab-generator to convert crontabs