Frage Kann ich häufiger als jede Minute einen Cron-Job ausführen?


Ist es möglich, einen Cron-Job alle 30 Sekunden ohne einen Schlafbefehl auszuführen?


39
2017-08-02 20:48


Ursprung


Was ist Deine Absicht? Ist Cron das richtige Werkzeug dafür? - Manuel Faux
Gute Frage. - Preet Sangha
Zum Beispiel verwende ich cron, um mein Desktop-Hintergrundbild zu ändern, um die Einschränkungen des nativen Hintergrundbild-Switches zu umgehen (nicht in Unterverzeichnisse einzutauchen). Wenn ich öfter als einmal pro Minute wechseln wollte, würde ich auf diese Cron-Begrenzung stoßen. (obwohl der native bg Switcher dieselbe Einschränkung hat) - donquixote


Antworten:


Wenn Ihre Aufgabe häufig ausgeführt werden muss, ist Cron das falsche Werkzeug. Abgesehen von der Tatsache, dass Jobs einfach nicht häufig gestartet werden, riskieren Sie auch einige ernsthafte Probleme, wenn der Job länger dauert als das Intervall zwischen den Starts. Schreiben Sie Ihre Aufgabe neu, um sie zu dämonisieren und dauerhaft auszuführen, und starten Sie sie anschließend bei Bedarf von cron aus (während Sie sicherstellen, dass sie nicht neu gestartet wird, wenn sie bereits ausgeführt wird).


38
2017-08-02 21:05



Der Teil "Sie riskieren auch einige schwerwiegende Probleme, wenn der Job länger dauert als das Intervall zwischen den Starts." ist nicht wahr, und wenn es war, würde es gleichermaßen für Jobs gelten, die alle 5 Minuten, jede Stunde oder jeden Monat für diese Angelegenheit laufen. Dieses Problem hat Lösungen (mit einer PID-Datei oder was auch immer und überprüft, ob der Job bereits ausgeführt wird, bevor es ausgeführt wird). Das Problem ist also, dass cron diese Frequenz nicht zulassen wird, aber es ist falsch zu sagen, dass es etwas intrinsisch falsch ist, eine Aufgabe alle weniger als eine Minute auszuführen. - matteo
Ich meinte, wenn du kein Pidfile verwendest. Wenn Ihr Job alle X Minuten ausgeführt wird und mehr als X Minuten benötigt, um zu beenden, werden Sie mit dem Stapeln von Jobs enden. Wenn Ihr Job auch durch eine Ressource begrenzt ist (CPU, Netzwerk- / Festplattenbandbreite, etc.), wird es immer länger dauern, bis Sie fertig sind, und Ihr Computer wird sich schließlich in ein Durcheinander verwandeln. - duskwuff
Sie können verwenden run-one um sicherzustellen, dass ein Programm / sogar ein PHP-Skript keine doppelte Instanz startet. sudo apt-get install run-one und rufe es an run-one <normal command> - kouton
Wie die Antworten weiter unten zeigen, ist es sehr gut möglich, wenn auch ein bisschen hackisch. Warum tust du es falsch? die akzeptierte Antwort hier, wenn sie die Frage überhaupt nicht beantwortet? - Someone
@Mantriur Weil der Autor der Frage es hilfreich fand und als die akzeptierte Antwort markierte? Aber im Ernst, Sie haben das Problem bereits selbst erkannt: Viele der anderen zeitgenössischen Antworten schlugen haschische Lösungen vor, die in einem Produktionssystem nicht sinnvoll wären. (Beachten Sie auch, dass einige der anderen Antworten erst Jahre nach der Frage angezeigt wurden, sodass sie noch nicht akzeptiert werden konnten!) - duskwuff


Kandidat für die kreativste  Missbrauch eines Linux-Befehls:

nohup watch -n 30 --precise yourprog >/dev/null &

Ob yourprog besteht aus:

date +%M.%S.%N >> yourprog.out

dann yourprog.out könnte aussehen wie:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

was ein ziemlich gutes Maß an Präzision anzeigt.

Hier ist eine Erklärung der Teile des Befehls:

  • nohup - Dies hält den folgenden Befehl, watch in diesem Fall aus dem Beenden, wenn das Terminal austritt.
  • watch - Dieses Programm führt wiederholt einen Befehl aus. Normalerweise wird jedes Mal der erste Bildschirm mit der Ausgabe des Befehls angezeigt watch Führt den Befehl aus.
  • -n 30 - Das Intervall, in dem der Befehl ausgeführt werden soll. In diesem Fall sind es alle 30 Sekunden.
  • --precise - Ohne diese Option watch Führt den Befehl aus nach dem  Intervall Sekunden. Mit ihm jeden Start des Befehls beginnt  auf das Intervall wenn möglich. Wenn diese Option im Beispiel nicht angegeben wäre, würden die Zeiten aufgrund der Zeit, die zum Starten und Ausführen des Befehls benötigt wird, später und später um mehr als 30 Sekunden verstreichen (yourprog).
  • yourprog - Das Programm oder die Befehlszeile für watch ausführen. Wenn die Befehlszeile spezielle Zeichen für die Shell enthält (z. B. Leerzeichen oder Semikolon), muss sie in Anführungszeichen gesetzt werden.
  • >/dev/null - Der Größer-als-Befehl leitet die Ausgabe des Befehls um, von dem er ausgeführt wird watch in eine Datei, /dev/null. Diese Datei verwirft alle darauf geschriebenen Daten. Dies verhindert, dass die Ausgabe auf den Bildschirm geschrieben wird, oder seit nohup Wird verwendet, verhindert es, dass die Ausgabe an eine Datei namens code gesendet wird nohup.out.
  • & - Das watch Befehl wird im Hintergrund ausgeführt, und die Steuerung wird an den Terminal- oder übergeordneten Prozess zurückgegeben.

Beachten Sie, dass nohup, die Umleitung der Ausgabe und der & Hintergrundsteueroperator sind nicht spezifisch für watch.

Hier ist eine Erklärung des Beispiels yourprog Skript:

  • date - Gibt das aktuelle Datum und / oder die aktuelle Uhrzeit aus. Es kann sie auch einstellen.
  • +%M.%S.%N - Dies legt das Ausgabeformat für fest date benutzen. %M ist die aktuelle Minute, %S ist die aktuelle Sekunde und %N ist die aktuelle Nanosekunde.
  • >> yourprog.out - Dies leitet die Ausgabe des date Befehl an eine Datei namens yourprog.out. Der doppelte Wert größer als bewirkt, dass die Ausgabe bei jedem Aufruf an die Datei angehängt wird, statt dass der vorherige Inhalt überschrieben wird.

Bearbeiten:

Möglicherweise ist eine andere Sache, die missbraucht werden könnte (oder vielleicht ist es eine legitime Verwendung) Systemd-Timer.

Sehen systemd / Timer als Cron-Ersatz und Cron vs Systemd Timer.

Ich werde versuchen, bald ein Beispiel zu veröffentlichen.


34
2017-08-16 13:58



Ich gebe +1 für reine Wange - Matt Simmons
Wäre schön, ein bisschen mehr Erklärung mit dieser Antwort zu haben. Der nohup Befehl ist neu für mich. Das Internet sagt mir, dass es das Hangup-Signal ignorieren soll. Was mich immer noch verwirrt. - donquixote
@ Donquixote: Es ist wichtig zu erkennen, dass der Befehl als Ganzes in meiner Antwort nicht empfohlen ist, daher die Verwendung des Wortes "Missbrauch". Um jedoch etwas für Sie zu klären, da es nützliche Techniken gibt, werde ich versuchen, einige zu beschreiben. Das & bewirkt, dass der Befehl im Hintergrund ausgeführt wird und die Steuerung sofort an die Eingabeaufforderung zurückgegeben wird. Verwendung der nohup Befehl verursacht den Hintergrundprozess (in diesem Fall watch) um das Aufhängungssignal zu ignorieren, das gesendet wird, wenn die Shell beendet wird, beispielsweise wenn Sie das Terminal schließen. ... - Dennis Williamson
... Ausgabe umleiten mit >/dev/null bewirkt, dass die Ausgabe verworfen wird und verhindert die Erstellung von nohup.out Datei, die sonst erstellt würde, wenn die Standardausgabe ein Terminal ist. - Dennis Williamson
@ Donquixote: Nicht nur 30 Sekunden, alle 30 Sekunden. Der Rest besteht darin, dass es unbeaufsichtigt im Hintergrund läuft, um cronartiger zu sein. Wenn du es benutzen wolltest sleep, müssten Sie eine Schleife schreiben, damit sich der Prozess wiederholt (watch Wiederholt das für Sie, wie es auch ist cron). Du würdest immer noch brauchen nohup und &. Ein zusätzliches Problem mit sleep wäre Zeitdrift. Das --precise Option von watch vermeidet dies. Ohne es oder bei der Verwendung sleep In einer Schleife hat das Zeitintervall die Zeit, die für die Ausführung der Befehle oder des Skripts benötigt wird, damit jeder Lauf später und später als ... - Dennis Williamson


Cron ist so konzipiert, dass es jede Minute aufwacht. Daher ist es nicht möglich, es ohne Hacking zu tun.


14
2017-08-02 20:53





* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

Vergessen Sie nicht, etwas in Ihr Programm zu schreiben, damit es beendet wird, wenn bereits eine vorherige Instanz läuft.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Natürlich bleibt dabei nur eine sehr geringe Chance zu scheitern. Suchen Sie also nach einer besseren Lösung für Ihre Umgebung.


9
2017-12-16 19:32



es wurde gefragt: without a sleep command - philippe
Anderen Besuchern, die diese Frage finden, ist es egal, ob der Schlafbefehl verwendet wird :) - donquixote


Sie können dies mit Software von Drittanbietern tun.

Eine Option, die für mich gut funktioniert hat häufig-cron

Es ermöglicht Millisekunden-Genauigkeit und es gibt Ihnen die Möglichkeit, die nächste Ausführung zu verschieben, bis der aktuelle beendet wurde.


8
2017-10-30 05:11



Frequent-Cron hat auch für uns gut funktioniert und viele unserer Produktionssysteme angetrieben. Wir hatten nie ein Problem damit. - Homer6


Ich hätte ein paar Bedenken:

(1) Manchmal ist ein System beschäftigt und kann die Dinge nicht genau an dem 30-Sekunden-Punkt starten. Es ist dann möglich, dass zur selben Zeit, zu der Sie einen Job ausführen, ein anderer Job erscheint und dann 2 (oder mehr) Jobs dasselbe tun Ding. Je nach Skript kann es hier zu erheblichen Störungen kommen. Daher sollte das Codieren in einem solchen Skript etwas Code enthalten, um sicherzustellen, dass nur eine Instanz des gegebenen Skripts zur gleichen Zeit ausgeführt wird.

(2) Das Skript könnte möglicherweise viel Overhead haben und mehr Systemressourcen verbrauchen, als Sie vielleicht möchten. Dies gilt, wenn Sie gegen viele andere Systemaktivitäten konkurrieren.

Wie ein Poster es ausgedrückt hat, würde ich in diesem Fall ernsthaft erwägen, einen Daemon einzusetzen, der mit zusätzlichen Prozessen läuft, um sicherzustellen, dass er weiterläuft, wenn er für Ihre Operationen von entscheidender Bedeutung ist.


2
2017-08-02 21:26





Eine Lösung, wenn es für Ihr eigenes Skript ist oder Sie es umbrechen können:

  1. Erhalte und erinnere dich an die Startzeit.
  2. Wenn eine Sperrdatei, die Sie später berühren werden, vorhanden ist und das Skript 60 Sekunden lang nicht ausgeführt wurde, warten Sie eine Sekunde und überprüfen Sie erneut. (z.B. während / schlafen) *
  3. Wenn die Sperrdatei nach Ablauf von 60 Sekunden noch immer vorhanden ist, beenden Sie sie mit einer veralteten Sperrwarnung.
  4. Berühre die Sperrdatei.
  5. Während das Skript 60 Sekunden lang nicht ausgeführt wurde, führen Sie die aktuelle Task mit der gewünschten Schlafdauer durch.
  6. Löschen Sie die Sperrdatei.
  7. Fügen Sie als Minuten Cron hinzu.
  8. Bob ist Dein Onkel.

Weniger Kopfschmerzen als das Erstellen und Überwachen eines Dämons.

* Wenn Sie PHP verwenden, erinnern Sie sich an clearstatcache ().


0
2018-05-23 21:31





Meine einfachste und bevorzugte Lösung für diese Aufgabe:

Cron-Eintrag:
* * * * * flock -w0 /path/to/script /path/to/script

Skript:
while true;do echo doing something; sleep 10s;done

faule Alternative: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

oder

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

Profis

  • Gebrauch von flock Der Befehl verhindert, dass das Skript gleichzeitig von mehreren Instanzen ausgeführt wird. Es kann in den meisten Fällen sehr wichtig sein.
  • flock und watch Befehle sind bei den meisten Linux-Installationen verfügbar

Nachteile

  • Das Beenden dieser Art von "Service" benötigt zwei Schritte
    • Kommentieren Sie den Cron-Eintrag
    • Töte das Skript oder die watch Befehl

0
2017-10-17 13:11



Kann jemand dies einem Linux-Neuling erklären - mit Vor- und Nachteilen? Vielen Dank .. - a20