Frage Verhindern Sie, dass doppelte Cron-Jobs ausgeführt werden


Ich habe einen Cron-Job geplant, der jede Minute ausgeführt wird, aber manchmal dauert es mehr als eine Minute, bis das Skript beendet ist, und ich möchte nicht, dass die Jobs "übereinander" gestapelt werden. Ich denke, das ist ein Nebenläufigkeitsproblem - d. H. Die Skriptausführung muss sich gegenseitig ausschließen.

Um das Problem zu lösen, habe ich das Skript nach der Existenz einer bestimmten Datei suchen lassen ("lockfile.txt") und beenden, wenn es existiert oder touch wenn nicht. Aber das ist ein ziemlich mieser Semaphor! Gibt es eine Best Practice, über die ich Bescheid wissen sollte? Soll ich stattdessen einen Daemon geschrieben haben?


81
2017-11-09 11:32


Ursprung




Antworten:


Es gibt ein paar Programme, die diese Funktion automatisieren, den Ärger und potentielle Bugs entfernen, die Sie selbst machen, und das Problem der altbackenen Schlösser vermeiden, indem Sie auch Flock hinter den Kulissen verwenden (was ein Risiko ist, wenn Sie nur die Berührung verwenden) . Ich habe gebraucht lockrun und lckdo in der Vergangenheit, aber jetzt gibt es flock(1) (in neueren Versionen von util-linux), das ist großartig. Es ist wirklich einfach zu bedienen:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job

109
2017-11-09 11:57



lckdo wird aus moreutils entfernt, jetzt, da flock (1) in util-linux ist. Und dieses Paket ist in Linux-Systemen grundsätzlich verpflichtend, also sollten Sie sich auf seine Präsenz verlassen können. Zur Verwendung, siehe unten. - jldugger
Ja, Herde ist jetzt meine bevorzugte Option. Ich werde sogar meine Antwort aktualisieren. - womble♦
Kennt jemand den Unterschied zwischen flock -n file command und flock -n file -c command ? - Nanne
@ Nanne, ich müsste den Code überprüfen, aber meine Vermutung ist, dass -c Läuft den angegebenen Befehl über eine Shell (wie auf der Manpage), während das "bare" (nicht-c) Form einfach execs der Befehl gegeben. Wenn Sie etwas durch die Shell einfügen, können Sie Shell-ähnliche Dinge tun (z. B. das Ausführen mehrerer Befehle, die mit getrennt werden) ; oder &&), aber öffnet auch Sie Shell-Erweiterung Angriffe, wenn Sie nicht vertrauenswürdige Eingabe verwenden. - womble♦
Es war ein Argument für die (hypothetische) frequent_cron_job Befehl, der versuchte zu zeigen, dass es jede Minute ausgeführt wurde. Ich habe es entfernt, da es nichts nützliches hinzugefügt hat und Verwirrung verursacht hat (deines, wenn niemand sonst im Laufe der Jahre). - womble♦


Der beste Weg in der Shell ist zu verwenden Herde (1)

(
  flock -x -w 5 99
  ## Do your stuff here
) 99>/path/to/my.lock

27
2017-11-09 11:45



Ich kann eine knifflige Verwendung der fd-Umleitung nicht verbessern. Es ist einfach zu unglaublich großartig. - womble♦
Pars für mich nicht in Bash oder ZSH, muss den Abstand zwischen löschen 99 und > so ist es 99> /... - Kyle Brandt♦
@ Javier: Bedeutet nicht, dass es nicht schwierig und geheimnisvoll ist, nur dass es ist dokumentiert, trickreich und geheimnisvoll. - womble♦
Was würde passieren, wenn Sie während der Ausführung neu starten oder den Prozess irgendwie beenden? Wäre es für immer verschlossen? - Alex R
Ich verstehe, dass diese Struktur eine exklusive Sperre erzeugt, aber ich verstehe die Mechanik nicht, wie dies erreicht wird. Was ist die Funktion der '99' in dieser Antwort? Wer möchte das bitte erklären? Vielen Dank! - Asciiom


Tatsächlich, flock -n kann anstelle von verwendet werden lckdo*, also werden Sie Code von Kernel-Entwicklern verwenden.

Aufbauend auf das Beispiel von Womble, du würdest etwas schreiben wie:

* * * * * flock -n /some/lockfile command_to_run_every_minute

BTW, Blick auf den Code, alle flock, lockrun, und lckdo genau dasselbe tun, es ist nur eine Frage, die Ihnen am leichtesten zugänglich ist.

* Da ich aufgrund meines Rufes zum Zeitpunkt des Schreibens keine der vorherigen Antworten bearbeiten oder kommentieren kann, muss ich dies als separate Antwort schreiben.


21
2017-11-19 22:43





Sie können eine Sperrdatei verwenden. Erstellen Sie diese Datei beim Start des Skripts und löschen Sie sie nach Abschluss des Skripts. Bevor das Script seine Hauptroutine ausführt, sollte es prüfen, ob die Sperrdatei existiert und entsprechend vorgehen.

Lockfiles werden von Initskripten und vielen anderen Anwendungen und Dienstprogrammen in Unix-Systemen verwendet.


2
2017-11-09 11:36



Dies ist das nur wie ich es jemals persönlich umgesetzt habe. Ich benutze nach dem Vorschlag des Betreuers als Spiegel für ein OSS-Projekt - warren


Dies könnte auch ein Zeichen dafür sein, dass Sie das Falsche tun. Wenn Ihre Jobs so eng und häufig ausgeführt werden, sollten Sie vielleicht in Erwägung ziehen, sie zu dekonponieren und zu einem Daemon-ähnlichen Programm zu machen.


1
2017-11-09 11:45



Dem widerspreche ich herzlich. Wenn Sie etwas haben, das regelmäßig ausgeführt werden muss, ist es ein "Vorschlaghammer für eine Nuss" -Lösung. Die Verwendung einer Sperrdatei zur Vermeidung von Unfällen ist eine vollkommen vernünftige Lösung, für die ich nie ein Problem hatte. - womble♦
@ Womble Ich stimme zu; aber ich mag Nüsse mit Vorschlaghämmern! :-) - wzzrd


Sie haben nicht angegeben, ob das Skript auf die Ausführung des vorherigen Laufs warten soll oder nicht. Mit "Ich möchte nicht, dass die Jobs gestartet werden" stapeln sich "übereinander". Ich schätze also, Sie möchten, dass das Skript beendet wird, wenn es bereits ausgeführt wird.

Also, wenn Sie nicht auf lckdo oder ähnliches angewiesen sind, können Sie dies tun:


PIDFILE=/tmp/`basename $0`.pid

if [ -f $PIDFILE ]; then
  if ps -p `cat $PIDFILE` > /dev/null 2>&1; then
      echo "$0 already running!"
      exit
  fi
fi
echo $$ > $PIDFILE

trap 'rm -f "$PIDFILE" >/dev/null 2>&1' EXIT HUP KILL INT QUIT TERM

# do the work


1
2017-11-09 14:33



Vielen Dank, dass Ihr Beispiel hilfreich ist. Ich möchte, dass das Skript beendet wird, wenn es bereits ausgeführt wird. Danke fürs Erwähnen Ickdo - Es scheint der Trick zu sein. - Tom


Ihr Cron-Daemon sollte keine Jobs aufrufen, wenn vorherige Instanzen noch ausgeführt werden. Ich bin der Entwickler eines Cron-Daemons dcronund wir versuchen das konkret zu verhindern. Ich weiß nicht, wie Vixie Cron oder andere Dämonen damit umgehen.


1
2018-02-17 15:59