Planen Sie den Befehl zur Ausführung zu einem bestimmten Zeitstempel mit systemd

Planen Sie den Befehl zur Ausführung zu einem bestimmten Zeitstempel mit systemd

Ich möchte einen Befehl so planen, dass er zu einem bestimmten Zeitpunkt ausgeführt wird, der durch einen Unix-Zeitstempel identifiziert wird. Es scheint, als wäre dies mit systemd mithilfe von möglich systemd-run, aber wie würde das funktionieren? Und was würde mit dem geplanten Befehl passieren, wenn die Maschine zum Zeitpunkt der Planung des Befehls ausgeschaltet oder angehalten wird?

Verwandte Frage: Dasselbe mit „ atvon“ tun atd(dazu muss der Zeitstempel wieder in ein Datum umgewandelt werden):Ist es möglich, mit dem Befehl „at“ die Ausführung eines Jobs zu einem bestimmten Zeitstempel zu planen?

Antwort1

systemd-runSie können einen Befehl so planen, dass er zu einem bestimmten Zeitpunkt ausgeführt wird.so lange wie:

  • Das System wird nicht vor diesem Zeitpunkt heruntergefahren, da es eine temporäre Timer- und Servicedatei in /run schreibt, die beim Neustart gelöscht wird.
  • Das System wird während dieser bestimmten Zeit nicht angehalten, es sei denn, Sie verwenden die Option „WakeSystem“ (siehe unten).

Eine Option zum dauerhaften Neustart finden Sie weiter unten.

Ein einfaches Beispiel für systemd-run:

# generate an arbitrary timestamp, in seconds-since-the-epoch
timestamp=$(date -d 'now + 42 seconds' +%s)
systemd-run --on-calendar "$(date -d @"$timestamp" +'%F %T')" \
  --timer-property=AccuracySec=1us \
  touch /tmp/done

Die wichtigen Teile für die systemd-runVerwendung eines Zeitstempels „Sekunden seit der Epoche“ sind:

  • zu verwenden --on-calendarund
  • hier wird GNU date verwendet, um den Zeitstempel der Sekunden seit der Epoche in ein Format umzuwandeln, das systemd-runes versteht. Sie können den Zeitstempel selbst eingeben oder konvertieren, solange das Ergebnis in einemFormat, das OnCalendar versteht.

Die aktuelle Dokumentation für OnCalendar gibt an, dass es die Eingabe in einem Sekunden-seit-der-Epoche-Zeitstempel direkt unterstützt. Diese '@seconds'-Unterstützung wurde hinzugefügt insystemd Version 234(suchen Sie auf dieser Seite nach der Datei src/basic/calendarspec.c) inbegehen d80e5b7. Ihre Version von systemd ist möglicherweise älter als diese Änderung. Beispiele:

  • RHEL 7 begann mit systemd 208 und wurde später auf Version 219 aktualisiert; RHEL 8 verwendet Version 239 (Referenz).
  • Debian 8 verwendete Version 215, Debian 9 verwendete Version 232 und Debian 10 verwendet Version 241 (Referenz).
  • Ubuntu 16.04 LTS hatte Version 229, Ubuntu 17.10 hatte Version 234 und Ubuntu 18.04 LTS hatte Version 237 (Referenz).

Mit einer ausreichend neuen Version von systemd könnten Sie diesen Aufruf verwenden:

timestamp=$(date -d 'now + 42 seconds' +%s)
systemd-run --on-calendar "@${timestamp}" \
  --timer-property=AccuracySec=1us \
  touch /tmp/done

Ich habe auch gezeigt,Timer-Eigenschaft von AccuracySec, der standardmäßig auf 1 Minute eingestellt ist und dessen Wert Sie basierend auf der Dokumentation anpassen sollten:

Um den Stromverbrauch zu optimieren, stellen Sie diesen Wert so hoch wie möglich und so niedrig wie nötig ein.

Ich habe es nicht getestet, aber es gibt auch eine Timer-Option namens „, WakeSystemdie Folgendes tun würde:

bewirkt, dass das System aus dem Ruhezustand wieder aufgenommen wird, falls es in den Ruhezustand versetzt wurde und das System dies unterstützt. Beachten Sie, dass diese Option nur sicherstellt, dass das System zu den entsprechenden Zeiten wieder aufgenommen wird. Sie kümmert sich nicht darum, es erneut in den Ruhezustand zu versetzen, nachdem die auszuführende Arbeit abgeschlossen ist.

Sie würden es in das Obige folgendermaßen integrieren:

timestamp=$(date -d 'now + 42 seconds' +%s)
systemd-run --on-calendar "$(date -d @"$timestamp" +'%F %T')" \
  --timer-property=AccuracySec=1us \
  --timer-property=WakeSystem=true \
  touch /tmp/done

Um systemd aufzufordern, einen Befehl zu einer bestimmten Zeit auszuführen, und zwar auf eine Weise, diebleibt über einen Neustart hinaus bestehen, und das unabhängig von einer bestimmten Anmeldesitzung ist, müssten Sie Timer- und Service-Unit-Dateien unter platzieren /etc/systemd/system/./etc/systemd/system ist der Ort, an dem die lokale Konfiguration gespeichert istfür systemd.

Ein Beispiel für eine Timerdatei wäre:

[Timer]
AccuracySec=1us
[Unit]
Description=2020-01-22 09:50:00 timer
[Timer]
OnCalendar=2020-01-22 09:50:00

und eine Beispiel-Servicedatei wäre:

[Unit]
Description=my 2020-01-22 09:50:00 service
[Service]
ExecStart=
ExecStart=@/usr/bin/bash "/usr/bin/bash" "-c" "echo 2020-01-22 09:50:00 timer and service ran > /tmp/done"

Anschließend würden Sie systemd über die Dateien informieren, indem Sie es neu laden:

systemctl daemon-reload

... und anschließend den Timer aktivieren:

systemctl enable foo.timer

... und anschließend den Timer starten:

systemctl start foo.timer

Möglicherweise möchten Sie abgelaufene Timer und Service-Einheiten regelmäßig aus /etc/systemd/system entfernen, sobald ihre Zeit abgelaufen ist.

verwandte Informationen