Ich habe geplant, dass ein Cron-Job jede Minute ausgeführt wird, aber manchmal dauert es mehr als eine Minute, bis das Skript fertig ist, und ich möchte nicht, dass die Jobs sich gegenseitig überlagern. Ich denke, dies ist ein Nebenläufigkeitsproblem - dh die Skriptausführung muss sich gegenseitig ausschließen.
Um das Problem zu lösen, habe ich das Skript veranlasst, nach einer bestimmten Datei (" lockfile.txt ") zu suchen und zu beenden, wenn sie existiert oder touch
nicht. Aber das ist ein ziemlich mieses Semaphor! Gibt es eine bewährte Methode, die ich kennen sollte? Sollte ich stattdessen einen Daemon geschrieben haben?
quelle
flock -n file command
undflock -n file -c command
?-c
der angegebene Befehl über eine Shell ausgeführt wird (wie in der Manpage angegeben), während die "nackte" (nicht-c
) Form nurexec
der angegebene Befehl ist . Wenn Sie etwas in die Shell einfügen, können Sie Shell-ähnliche Aktionen ausführen (z. B. mehrere mit;
oder getrennte Befehle ausführen&&
). Sie können jedoch auch Shell-Erweiterungsangriffe ausführen , wenn Sie nicht vertrauenswürdige Eingaben verwenden.frequent_cron_job
Befehl, der zu zeigen versuchte, dass er jede Minute ausgeführt wurde. Ich habe es entfernt, da es nichts Nützliches hinzufügt und Verwirrung stiftet (deins, wenn über die Jahre niemand anderes mehr da ist).Der beste Weg in der Schale ist die Verwendung von Herde (1)
quelle
99
und>
so ist es99> /...
Tatsächlich
flock -n
kann anstelle vonlckdo
* auch Code von Kernel-Entwicklern verwendet werden.Aufbauend auf dem Beispiel von womble würden Sie etwa schreiben:
BTW, Blick auf den Code, die alle
flock
,lockrun
undlckdo
tun genau dasselbe, es ist also nur eine Frage von denen am ehesten für Sie verfügbar ist.quelle
Sie können eine Sperrdatei verwenden. Erstellen Sie diese Datei, wenn das Skript gestartet wird, und löschen Sie sie, wenn sie beendet ist. Bevor das Skript seine Hauptroutine ausführt, sollte es prüfen, ob die Sperrdatei vorhanden ist, und entsprechend vorgehen.
Sperrdateien werden von Initscripts und vielen anderen Anwendungen und Dienstprogrammen in Unix-Systemen verwendet.
quelle
Sie haben nicht angegeben, ob das Skript auf den Abschluss der vorherigen Ausführung warten soll oder nicht. Mit "Ich möchte nicht, dass die Jobs sich" übereinander "stapeln", gehen Sie vermutlich davon aus, dass das Skript beendet werden soll, wenn es bereits ausgeführt wird.
Wenn Sie sich also nicht auf lckdo oder ähnliches verlassen möchten, können Sie dies tun:
quelle
Dies könnte auch ein Zeichen dafür sein, dass Sie das Falsche tun. Wenn Ihre Jobs so eng und so häufig ausgeführt werden, sollten Sie möglicherweise in Betracht ziehen, sie zu entfernen und sie zu einem Programm im Dämon-Stil zu machen.
quelle
Ihr Cron-Daemon sollte keine Jobs aufrufen, wenn frühere Instanzen von ihnen noch ausgeführt werden. Ich bin der Entwickler von einem Cron-Daemon- Dcron , und wir versuchen dies ausdrücklich zu verhindern. Ich weiß nicht, wie Vixie Cron oder andere Dämonen damit umgehen.
quelle
Ich würde die Verwendung des Befehls run-one empfehlen - viel einfacher als das Behandeln der Sperren. Aus den Dokumenten:
run-one ist ein Wrapper-Skript, das nicht mehr als eine eindeutige Instanz eines Befehls mit einem eindeutigen Satz von Argumenten ausführt. Dies ist häufig bei Cronjobs hilfreich, wenn Sie nicht mehr als eine Kopie gleichzeitig ausführen möchten.
run-this-one ist genau wie run-one, außer dass es pgrep und kill verwendet, um alle laufenden Prozesse zu finden und zu beenden, die dem Benutzer gehören und mit den Zielbefehlen und -argumenten übereinstimmen. Beachten Sie, dass run-this-one blockiert, während versucht wird, übereinstimmende Prozesse abzubrechen, bis alle übereinstimmenden Prozesse beendet sind.
run-one-constant funktioniert genauso wie run-one, außer dass es "COMMAND [ARGS]" bei jedem Beenden von COMMAND erneut ausgibt (null oder nicht null).
Keep-One-Running ist ein Alias für Run-One-Constant.
run-one-until-success funktioniert genauso wie run-one-constant, mit der Ausnahme, dass es "COMMAND [ARGS]" erneut ausgibt, bis COMMAND erfolgreich beendet wird (dh Null verlässt).
run-one-until-failure funktioniert genauso wie run-one-constant, mit der Ausnahme, dass es "COMMAND [ARGS]" erneut erzeugt, bis COMMAND mit einem Fehler beendet wird (dh nicht Null endet).
quelle
Nachdem systemd jetzt nicht mehr verfügbar ist, gibt es auf Linux-Systemen einen weiteren Planungsmechanismus:
EIN
systemd.timer
In
/etc/systemd/system/myjob.service
oder~/.config/systemd/user/myjob.service
:In
/etc/systemd/system/myjob.timer
oder~/.config/systemd/user/myjob.timer
:Wenn die Serviceeinheit bereits aktiviert ist, wenn der Timer das nächste Mal aktiviert wird, wird keine weitere Instanz des Service gestartet.
Eine Alternative, die den Job einmal beim Booten und eine Minute nach jedem Lauf startet:
quelle
Ich habe ein Glas erstellt, um ein solches Problem zu lösen, da doppelte Cron ausgeführt werden, z. B. Java oder Shell Cron. Übergeben Sie einfach den Cron-Namen in Duplicates.CloseSessions ("Demo.jar"). Dadurch wird die vorhandene PID für diesen Cron mit Ausnahme der aktuellen gesucht und beendet. Ich habe eine Methode implementiert, um dieses Zeug zu machen. String proname = ManagementFactory.getRuntimeMXBean (). GetName (); String pid = proname.split ("@") [0]; System.out.println ("Current PID:" + pid);
Und dann killid string mit dem Befehl again shell töten
quelle
@Philip Reynolds Antwort startet die Ausführung des Codes ohnehin nach Ablauf der Wartezeit von 5 Sekunden, ohne die Sperre zu erhalten. Im Anschluss an Flock scheint nicht zu funktionieren geändert ich @Philip Reynolds Antwort auf
damit der Code niemals gleichzeitig ausgeführt wird. Stattdessen wird der Prozess nach 5 Sekunden mit 1 beendet, wenn er bis dahin nicht die Sperre erhalten hat.
quelle