Wie man systemd Timer-Units erstellt und verwaltet
Erstellen, aktivieren, überwachen und beheben Sie Probleme mit Systemd-Timer-Einheiten anhand praktischer Beispiele für `.timer`, `.service`, `systemctl` und `journalctl`.
So erstellen und verwalten Sie Systemd-Timer-Einheiten
Systemd-Timer-Einheiten planen Aufgaben unter Linux, ohne auf Cron angewiesen zu sein. Wenn Ihr Server ein Backup, einen Bereinigungsjob, einen Health-Check oder einen Bericht zu einem vorhersagbaren Zeitpunkt ausführen muss, bietet Ihnen ein Systemd-Timer Planung, Dienstisolierung, Abhängigkeitsverwaltung und Protokolle an einem Ort.
Die Kernidee ist einfach: Die .timer-Datei legt fest, wann etwas ausgeführt wird, und die .service-Datei legt fest, was ausgeführt wird. Diese Trennung macht Timer mit systemctl einfach zu überprüfen und mit journalctl einfach zu debuggen.
Die Struktur einer Systemd-Timer-Einheit verstehen
Eine Systemd-Timer-Einheit ist immer mit einer entsprechenden Service-Einheit (oder einem anderen Einheitentyp) gepaart, die sie aktivieren soll. Die Timer-Einheit selbst definiert, wann die zugehörige Einheit aktiviert werden soll, während die Service-Einheit definiert, welche Aktion ausgeführt werden soll. Beide Einheiten befinden sich normalerweise im selben Verzeichnis, oft /etc/systemd/system/ für benutzerdefinierte Einheiten.
Eine typische Timer-Einheitendatei hat die Erweiterung .timer, und die zugehörige Service-Einheitendatei hat die Erweiterung .service. Wenn Sie z. B. eine in mytask.service definierte Aufgabe planen möchten, erstellen Sie eine Datei mytask.timer.
Beispiel: mytask.timer
[Unit]
Description=Run my custom task daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Lassen Sie uns die wichtigsten Abschnitte aufschlüsseln:
Abschnitt
[Unit]:Description: Eine menschenlesbare Beschreibung des Timers. Dies hilft bei der Identifizierung in Statusausgaben.
Abschnitt
[Timer]: Dies ist der Kern der Timer-Einheit und definiert die Planung.OnCalendar=daily: Diese Direktive gibt an, wann der Timer aktiviert werden soll.dailyist eine Kurzform für Mitternacht eines jeden Tages. Weitere Beispiele sind:hourly: Jede Stunde.weekly: Jede Woche (entsprichtMon *-*-* 00:00:00).Sun *-*-* 10:00: Jeden Sonntag um 10 Uhr.*-*-15 14:30: Am 15. jedes Monats um 14:30 Uhr.Mon..Fri *-*-* 09:00: An Wochentagen um 9 Uhr.
Persistent=true: Wenn dies auftruegesetzt ist, wird der Timer so schnell wie möglich aktiviert, wenn das Ereignis während der Systemabschaltung aufgetreten ist. BeiOnCalendar-Timern bedeutet dies, dass der Timer ausgelöst wird, sobald das System hochfährt und der Timer aktiv wird, wenn das System während der geplanten Zeit ausgeschaltet war.OnBootSec=: Aktiviert den Timer eine bestimmte Zeit nach dem Systemstart. Zum Beispiel würdeOnBootSec=15min15 Minuten nach dem Start auslösen.OnUnitActiveSec=: Aktiviert den Timer eine bestimmte Zeit, nachdem die von ihm aktivierte Einheit zuletzt aktiv wurde. Zum Beispiel plantOnUnitActiveSec=1heine weitere Ausführung eine Stunde, nachdem der zugehörige Dienst zuletzt aktiviert wurde.OnUnitInactiveSec=: Aktiviert den Timer eine bestimmte Zeit, nachdem die von ihm aktivierte Einheit zuletzt inaktiv wurde.AccuracySec=: Gibt die Genauigkeit des Timers an. Systemd versucht, das System nur dann für Timer aufzuwecken, wenn das Ereignis innerhalb dieses Zeitfensters liegt, was zum Stromsparen beiträgt. Standard ist1min.RandomizedDelaySec=: Fügt dem Timer-Auslöser eine zufällige Verzögerung bis zur angegebenen Dauer hinzu. Nützlich zur Lastverteilung.
Abschnitt
[Install]: Dieser Abschnitt definiert, wie die Timer-Einheit aktiviert werden kann.WantedBy=timers.target: Diese Direktive stellt sicher, dass der Timer bei Aktivierung Teil destimers.targetwird, einem Standard-Target, das alle aktiven Timer umfasst. Das bedeutet, dass der Timer nach der Aktivierung automatisch beim Booten startet.
Beispiel: mytask.service
[Unit]
Description=My custom task service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/my_custom_script.sh
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
Abschnitt
[Unit]:Description: Eine Beschreibung des Dienstes.
Abschnitt
[Service]: Dieser definiert den Dienst selbst.Type=oneshot: Geeignet für Aufgaben, die einmal ausgeführt werden und dann beenden. Es gibt andere Typen für langlebige Daemons.ExecStart: Der auszuführende Befehl. Stellen Sie sicher, dass das Skript Ausführungsberechtigungen hat.User/Group: Gibt den Benutzer und die Gruppe an, unter denen der Befehl ausgeführt werden soll. Es ist gute Praxis, Aufgaben nicht als root auszuführen, es sei denn, es ist unbedingt erforderlich.
Abschnitt
[Install]: Dieser Abschnitt wird normalerweise für einen Oneshot-Dienst nicht benötigt, der nur von einem Timer gestartet werden soll. Aktivieren Sie den Timer, nicht den Dienst.
Timer-Einheiten erstellen und aktivieren
Befolgen Sie diese Schritte, um Ihre Systemd-Timer-Einheiten zu erstellen und zu verwalten:
Erstellen Sie die Service-Einheitendatei: Definieren Sie Ihre Aufgabe in einer
.service-Datei. Platzieren Sie sie in/etc/systemd/system/(oder~/.config/systemd/user/für benutzerspezifische Timer).sudo nano /etc/systemd/system/mytask.serviceFügen Sie den obigen Beispiel-Service-Inhalt ein und speichern Sie ihn.
Erstellen Sie die Timer-Einheitendatei: Definieren Sie den Zeitplan in einer entsprechenden
.timer-Datei. Platzieren Sie sie im selben Verzeichnis wie die Service-Datei.sudo nano /etc/systemd/system/mytask.timerFügen Sie den obigen Beispiel-Timer-Inhalt ein und speichern Sie ihn.
Systemd-Daemon neu laden: Nach dem Erstellen oder Ändern von Einheitendateien müssen Sie systemd anweisen, seine Konfiguration neu zu laden.
sudo systemctl daemon-reloadTimer aktivieren: Damit der Timer automatisch beim Booten startet, aktivieren Sie ihn.
sudo systemctl enable mytask.timerHinweis: Sie aktivieren NICHT die Service-Datei, wenn sie ausschließlich vom Timer ausgelöst werden soll.
Timer starten: Starten Sie den Timer sofort. Er wird dann gemäß seinem Zeitplan ausgeführt.
sudo systemctl start mytask.timer
Timer-Einheiten verwalten und überwachen
Systemd bietet mehrere systemctl-Befehle zum Verwalten und Überwachen Ihrer Timer:
Alle Timer auflisten: Alle aktiven und inaktiven Timer anzeigen.
systemctl list-timersDieser Befehl liefert eine Ausgabe wie:
NEXT LEFT LAST PASSED UNIT ACTIVATES Tue 2023-10-27 08:00:00 UTC 10h left Wed 2023-10-26 08:00:00 UTC 14h ago mytask.timer mytask.serviceDies zeigt, wann der Timer als nächstes ausgeführt werden soll, wie lange es noch dauert, wann er zuletzt ausgeführt wurde und welchen Dienst er aktiviert.
Timer für eine bestimmte Einheit auflisten: Wenn Sie Timer sehen möchten, die sich auf einen bestimmten Dienst beziehen.
systemctl list-timers --all | grep mytask.serviceTimer-Status prüfen: Detaillierte Informationen zu einem bestimmten Timer erhalten.
systemctl status mytask.timerDies zeigt an, ob der Timer aktiv ist, wann er als nächstes ausgeführt werden soll und die letzten Protokolleinträge.
Dienstprotokolle anzeigen: Um die Ausgabe und den Status der vom Timer ausgeführten Aufgabe zu sehen, überprüfen Sie die Protokolle des zugehörigen Dienstes.
journalctl -u mytask.serviceSie können die Protokolle auch in Echtzeit verfolgen:
journalctl -f -u mytask.serviceTimer stoppen: Wenn Sie einen Timer vorübergehend deaktivieren müssen.
sudo systemctl stop mytask.timerTimer deaktivieren: Um zu verhindern, dass ein Timer beim Booten startet, und ihn zu stoppen, falls er läuft.
sudo systemctl disable --now mytask.timer
Erweiterte Timer-Konfigurationen
Bestimmte Intervalle festlegen
Anstelle von daily oder hourly können Sie genauere Intervalle definieren:
- Alle N Minuten:
OnUnitActiveSec=15min(wird 15 Minuten nach der letzten Aktivierung des Dienstes ausgeführt). - Bestimmte Zeiten:
OnCalendar=*-*-* 02:30:00(wird täglich um 2:30 Uhr ausgeführt). - Bedingungen kombinieren:
OnCalendar=Mon..Fri *-*-* 08:00:00(wird an Wochentagen um 8 Uhr ausgeführt).
AccuracySec zum Stromsparen verwenden
Wenn Ihre Aufgabe nicht zu einem genauen Zeitpunkt ausgeführt werden muss, sollten Sie AccuracySec verwenden. Zum Beispiel teilt AccuracySec=5min systemd mit, dass es in Ordnung ist, das System innerhalb von 5 Minuten nach der geplanten Zeit aufzuwecken. Dies ermöglicht es systemd, Timer-Ereignisse zu bündeln und das System möglicherweise länger in einem niedrigeren Energiezustand zu halten.
[Timer]
OnCalendar=hourly
AccuracySec=5min
Persistent vs. WakeSystem
Persistent=truestellt sicher, dass, wenn einOnCalendar-Ereignis aufgrund eines ausgeschalteten Systems verpasst wird, es beim nächsten Booten einmal ausgeführt wird. Dies ist entscheidend für Aufgaben, die nicht übersprungen werden dürfen.WakeSystem=truefordert systemd auf, das System aus dem Ruhezustand für den Timer aufzuwecken, wenn das System und die Hardware dies unterstützen. Es ist nicht dasselbe wie die Entscheidung, ob die Maschine mit Netzstrom oder Batterie betrieben wird.
Timer vs. Cron
| Funktion | Systemd-Timer | Cron |
|---|---|---|
| Integration | Tiefe Integration mit systemd-Diensten, Targets | Eigenständiges Dienstprogramm |
| Planung | Flexibel (Kalender, relativ, bootbasiert) | Hauptsächlich zeitbasierte Ausdrücke |
| Protokollierung | Zentralisiert über journalctl |
Verstreut (/var/log/syslog, /var/log/cron.log) |
| Fehlerbehandlung | Kann Aktionen an Dienstfehler binden | Grundlegende E-Mail-Benachrichtigungen |
| Abhängigkeiten | Kann von anderen aktiven Diensten abhängen | Eingeschränkt |
| Ausführung | Kann als bestimmte Benutzer, Gruppen ausgeführt werden | Kann über Crontab als bestimmte Benutzer ausgeführt werden |
| Energiemanagement | Kann für Stromsparen optimiert werden (AccuracySec) |
Weniger direkte Kontrolle |
Wann Sie Systemd-Timer wählen sollten:
- Wenn Sie eine engere Integration mit anderen systemd-Diensten benötigen.
- Wenn zentralisierte Protokollierung und einfachere Fehlersuche Priorität haben.
- Wenn Sie erweiterte Planungsoptionen benötigen (z. B. Zeit seit letzter Ausführung).
- Für Aufgaben im Zusammenhang mit dem Systemzustand oder Energiemanagement.
Wann Cron möglicherweise noch bevorzugt wird:
- Für sehr einfache, eigenständige Aufgaben auf Systemen, die systemd nicht vollständig nutzen.
- Für maximale Kompatibilität zwischen verschiedenen Linux-Distributionen und älteren Systemen.
Behebung häufiger Probleme
- Aufgabe wird nicht ausgeführt:
- Timer-Status prüfen:
systemctl status mytask.timer. Achten Sie aufActive: activeundTriggered...-Meldungen. - Dienstprotokolle prüfen:
journalctl -u mytask.service. Stellen Sie sicher, dass das Skript ausführbar ist und keine Fehler enthält. OnCalendar-Syntax überprüfen: Verwenden Siesystemd-analyze calendar 'your-calendar-string'zum Testen.- Stellen Sie sicher, dass der Timer aktiviert und gestartet ist:
systemctl list-timers --all.
- Timer-Status prüfen:
- Aufgabe läuft zu früh/zu spät:
- Überprüfen Sie
AccuracySecundRandomizedDelaySec. - Stellen Sie sicher, dass die Systemuhr genau ist (
timedatectl status).
- Überprüfen Sie
- Berechtigungsfehler:
- Bestätigen Sie, dass der in der
.service-Datei angegebeneUserund dieGroupdie erforderlichen Berechtigungen für das Skript und alle Dateien haben, auf die es zugreift. - Wenn kein Benutzer angegeben ist, wird standardmäßig root verwendet. Seien Sie vorsichtig mit Root-Rechten.
- Bestätigen Sie, dass der in der
Fazit
Verwenden Sie einen Systemd-Timer, wenn die Aufgabe zur Dienstebene der Maschine gehört: Backups, Bereinigungsaufgaben, Überwachungsprüfungen, Zertifikatserneuerungs-Hooks und andere betriebliche Arbeiten. Erstellen Sie zuerst den Dienst, dann den Timer, führen Sie systemctl daemon-reload aus, aktivieren und starten Sie den Timer, und überprüfen Sie ihn dann mit systemctl list-timers --all und journalctl -u your.service.