Nächste: , Vorige: , Nach oben: Dienste   [Inhalt][Index]


11.10.2 Geplante Auftragsausführung

It is often useful to have system tasks run periodically. This can be achieved by defining Shepherd timers or by using the historical and somewhat less flexible mcron service.

11.10.2.1 Shepherd Timers

The Shepherd supports running jobs periodically by defining timers, a special kind of service. A Shepherd timer can be defined like another Shepherd service, but with specific start and stop methods (siehe Shepherd-Dienste):

;; Defining a timer, verbosely.
(shepherd-service
 (provision '(updatedb))
 (requirement '(user-processes))
 (modules '((shepherd service timer)))
 (start #~(make-timer-constructor
           ;; Everyday at 3AM (using Vixie cron syntax).
           (cron-string->calendar-event "0 3 * * *")
           (command '(#$(file-append findutils "/bin/updatedb")))
           #:wait-for-termination? #t))
 (stop #~(make-timer-destructor))
 (documentation "Periodically run 'updatedb'.")
 (actions (list shepherd-trigger-action)))

This is quite some boilerplate so you can instead use this equivalent shorthand notation:

;; Equivalent timer definition, but shorter.
(shepherd-timer '(updatedb) "0 3 * * *"
                #~(#$(file-append findutils "/bin/updatedb"))
                #:requirement '(user-processes))

This procedure is defined as follows.

Procedure: shepherd-timer provision schedule command [#:requirement '()]  [#:documentation

%default-timer-documentation] Return a Shepherd service with the given provision periodically running command, a list-valued gexp, according to schedule, a string in Vixie cron syntax or a gexp providing a Shepherd calendar event. documentation is the string that appears when running herd doc service.

The example below shows how to define a timer and to add it to your operating system configuration.

(use-modules (gnu))
(use-service-modules shepherd)
(use-package-modules base)

(define updatedb-timer
  ;; Run 'updatedb' at 3AM everyday.
  (shepherd-timer '(updatedb)
                  "0 3 * * *"  ;Vixie cron syntax
                  #~(#$(file-append findutils "/bin/updatedb")
                     "--prunepaths=/tmp /var/tmp /gnu/store")
                  #:requirement '(user-processes)))

(define garbage-collection-timer
  ;; Run 'guix gc' everyday at 5AM.
  (shepherd-timer '(garbage-collection)
                  #~(calendar-event #:hours '(5) #:minutes '(0))
                  #~("/run/current-system/profile/bin/guix"
                     "gc" "-F" "10G")
                  #:requirement '(guix-daemon)))

(operating-system
  ;; …

  ;; Extend the Shepherd service with additional timers
  ;; using 'simple-service'.
  (services (cons (simple-service 'my-timers
                                   shepherd-root-service-type
                                   (list garbage-collection-timer
                                         updatedb-timer))
                  %base-services)))

The resulting system contains these two services, which can be inspected with herd status. They can also be triggered manually:

herd trigger garbage-collection

Siehe Timers in The GNU Shepherd Manual for more information on Shepherd timers.

11.10.2.2 Mcron

Alternatively, the (gnu services mcron) module provides an interface to GNU mcron, a daemon to run jobs at scheduled times (siehe GNU mcron). GNU mcron is similar to the traditional Unix cron daemon; the main difference is that it is implemented in Guile Scheme. It is overall less convenient than Shepherd timers: individual jobs cannot depend on specific Shepherd services, logging is coarse-grain (one file for all the jobs), jobs may not be inspected, updated, or triggered manually.

Anmerkung: For the reasons given above, we recommend using Shepherd timers rather than mcron for your periodic tasks.

Das folgende Beispiel definiert ein Betriebssystem, das täglich die Befehle updatedb (siehe Invoking updatedb in Finding Files) und guix gc (siehe guix gc aufrufen) ausführt sowie den Befehl mkid im Namen eines „unprivilegierten“ Nutzers ohne besondere Berechtigungen laufen lässt (siehe mkid invocation in ID Database Utilities). Zum Anlegen von Auftragsdefinitionen benutzt es G-Ausdrücke, die dann an mcron übergeben werden (siehe G-Ausdrücke).

(use-modules (guix) (gnu) (gnu services mcron))
(use-package-modules base idutils)

(define updatedb-job
  ;; 'updatedb' jeden Tag um 3 Uhr morgens ausführen. Hier schreiben wir
  ;; die vom Auftrag durchzuführende Aktion als eine Scheme-Prozedur.
  #~(job '(next-hour '(3))
         (lambda ()
           (system* (string-append #$findutils "/bin/updatedb")
                    "--prunepaths=/tmp /var/tmp /gnu/store"))
         "updatedb"))

(define garbage-collector-job
  ;; Jeden Tag 5 Minuten nach Mitternacht Müll sammeln gehen.
  ;; Die Aktion des Auftrags ist ein Shell-Befehl.
  #~(job "5 0 * * *"            ;Vixie-cron-Syntax
         "guix gc -F 1G"))

(define idutils-job
  ;; Die Index-Datenbank des Benutzers "charlie" um 12:15 Uhr und
  ;; 19:15 Uhr aktualisieren. Dies wird aus seinem Persönlichen
  ;; Ordner heraus ausgeführt.
  #~(job '(next-minute-from (next-hour '(12 19)) '(15))
         (string-append #$idutils "/bin/mkid src")
         #:user "charlie"))

(operating-system
  ;; …

  ;; In den %BASE-SERVICES kommt bereits eine Instanz des
  ;; 'mcron-service-type' vor. Wir erweitern sie um weitere
  ;; Aufträge mit einem 'simple-service'.
  (services (cons (simple-service 'my-cron-jobs
                                   mcron-service-type
                                   (list garbage-collector-job
                                         updatedb-job
                                         idutils-job))
                  %base-services)))

Tipp: Wenn Sie die Aktion einer Auftragsspezifikation als eine Prozedur angeben, sollten Sie ausdrücklich einen Namen für den Auftrag im dritten Argument angeben, wie oben im Beispiel zum updatedb-job gezeigt. Andernfalls wird für den Auftrag nur „Lambda function“ in der Ausgabe von herd schedule mcron angezeigt, was viel zu wenig Aussagekraft hat!

Tipp: Benutzen Sie nicht die Guile-Prozeduren execl, execle oder execlp in Auftragsspezifikationen, sonst wäre mcron nicht in der Lage, auszugeben, mit welchem Status der Auftrag abgeschlossen wurde.

Wenn Sie einen komplexeren Auftrag mit Scheme-Code auf oberster Ebene festlegen möchten, um zum Beispiel eine use-modules-Form einzuführen, können Sie Ihren Code in ein separates Programm verschieben, indem Sie die Prozedur program-file aus dem Modul (guix gexp) benutzen (siehe G-Ausdrücke). Das folgende Beispiel veranschaulicht dies.

(define %batterie-alarm-auftrag
  ;; Piepsen, wenn die Akkuladung in Prozent unter %MIN-NIVEAU fällt.
  #~(job
     '(next-minute (range 0 60 1))
     #$(program-file
        "batterie-alarm.scm"
        (with-imported-modules (source-module-closure
                                '((guix build utils)))
          #~(begin
              (use-modules (guix build utils)
                           (ice-9 popen)
                           (ice-9 regex)
                           (ice-9 textual-ports)
                           (srfi srfi-2))
              (define %min-niveau 20)
              (setenv "LC_ALL" "C")     ;Ausgabe auf Englisch
              (and-let* ((input-pipe (open-pipe*
                                      OPEN_READ
                                      #$(file-append acpi "/bin/acpi")))
                         (ausgabe (get-string-all input-pipe))
                         (m (string-match "Discharging, ([0-9]+)%" ausgabe))
                         (niveau (string->number (match:substring m 1)))
                         ((< niveau %min-niveau)))
                (format #t "Warnung: Batterieladung nur noch (~a%)~%" niveau)
                (invoke #$(file-append beep "/bin/beep") "-r5")))))))

Siehe mcron-Auftragsspezifikationen in GNU mcron für weitere Informationen zu mcron-Auftragsspezifikationen. Nun folgt die Referenz des mcron-Dienstes.

Wenn das System läuft, können Sie mit der Aktion schedule des Dienstes visualisieren lassen, welche mcron-Aufträge als Nächstes ausgeführt werden:

# herd schedule mcron

Das vorangehende Beispiel listet die nächsten fünf Aufgaben auf, die ausgeführt werden, aber Sie können auch angeben, wie viele Aufgaben angezeigt werden sollen:

# herd schedule mcron 10
Variable: mcron-service-type

Dies ist der Diensttyp des mcron-Dienstes. Als Wert verwendet er ein mcron-configuration-Objekt.

Dieser Diensttyp kann als Ziel einer Diensterweiterung verwendet werden, die ihn mit zusätzlichen Auftragsspezifikationen versorgt (siehe Dienstkompositionen). Mit anderen Worten ist es möglich, Dienste zu definieren, die weitere mcron-Aufträge ausführen lassen.

Datentyp: mcron-configuration

Verfügbare mcron-configuration-Felder sind:

mcron (Vorgabe: mcron) (Typ: dateiartig)

Welches mcron-Paket benutzt werden soll.

jobs (Vorgabe: '()) (Typ: Liste-von-G-Ausdrücken)

Dies muss eine Liste von G-Ausdrücken sein (siehe G-Ausdrücke), die jeweils einer mcron-Auftragsspezifikation (der Spezifikation eines „Jobs“) entsprechen (siehe mcron-Auftragsspezifikationen in GNU mcron).

log? (Vorgabe: #t) (Typ: Boolescher-Ausdruck)

Lässt Protokolle auf die Standardausgabe schreiben.

log-file (Vorgabe: "/var/log/mcron.log") (Typ: Zeichenkette)

Der Ort der Protokolldatei.

log-format (Vorgabe: "~1@*~a ~a: ~a~%") (Typ: Zeichenkette)

Eine Formatzeichenkette gemäß (ice-9 format) für die Protokollnachrichten. Mit dem Vorgabewert werden Nachrichten in der Form ‘Prozesskennung Name: Nachricht’ geschrieben (siehe Aufrufen von mcron in GNU mcron). Außerdem schreibt GNU Shepherd vor jeder Nachricht einen Zeitstempel.

date-format (Typ: Vielleicht-Zeichenkette)

Formatzeichenkette gemäß (srfi srfi-19) für das Datum.


Nächste: Log-Rotation, Vorige: Basisdienste, Nach oben: Dienste   [Inhalt][Index]