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

44

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

user15336
quelle
4
Was ist Deine Absicht? Ist cron das richtige Werkzeug dafür?
Manuel Faux
Gute Frage.
Preet Sangha
Zum Beispiel verwende ich derzeit cron, um mein Desktop-Hintergrundbild zu ändern, um Einschränkungen des nativen Hintergrundbild-Umschalters zu umgehen (nicht um in Unterverzeichnisse zu springen). Wenn ich öfter als einmal pro Minute wechseln wollte, stieß ich auf diese Cron-Einschränkung. (obwohl der native BG Switcher die gleiche Einschränkung hat)
donquixote

Antworten:

36

Wenn Ihre Aufgabe so häufig ausgeführt werden muss, ist cron das falsche Tool. Abgesehen von der Tatsache, dass Jobs einfach nicht so häufig gestartet werden, riskieren Sie auch einige schwerwiegende Probleme, wenn die Ausführung des Jobs 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 dann bei Bedarf von cron aus (und stellen Sie dabei sicher, dass sie nicht erneut gestartet wird, wenn sie bereits ausgeführt wird).

duskwuff
quelle
18
Der Teil "Sie riskieren auch einige ernsthafte Probleme, wenn die Ausführung des Jobs länger dauert als das Intervall zwischen den Starts." ist nicht wahr, und wenn dies der Fall wäre, würde dies auch für Jobs gelten, die alle 5 Minuten, jede Stunde oder jeden Monat ausgeführt werden. Dieses Problem hat Lösungen (mithilfe einer PID-Datei oder was auch immer und Überprüfen, ob der Job bereits ausgeführt wird, bevor es ausgeführt wird). Das Problem ist also, dass cron diese Frequenz einfach nicht zulässt, aber es ist falsch zu sagen, dass bei der Ausführung einer Aufgabe alle weniger als eine Minute ein Fehler vorliegt.
Matteo
2
Ich meinte, wenn Sie kein Pidfile verwenden. Wenn Ihr Job alle X Minuten ausgeführt wird und mehr als X Minuten dauert, werden Jobs gestapelt. Wenn Ihr Job auch durch eine bestimmte Ressource (CPU, Netzwerk- / Festplattenbandbreite usw.) begrenzt ist, dauert das Ausführen von mehr gleichzeitig noch länger, und Ihr Computer wird schließlich zu einem Chaos.
Duskwuff
2
Sie können run-onedamit sicherstellen, dass ein Programm / sogar ein PHP-Skript keine doppelte Instanz startet. sudo apt-get install run-oneund nenne es byrun-one <normal command>
kouton
3
Wie die Antworten weiter unten zeigen, ist es sehr gut möglich, wenn auch etwas hackisch. Warum tust du es falsch? die akzeptierte Antwort hier, wenn sie die Frage überhaupt nicht beantwortet?
Jemand
@Mantriur Weil der Autor der Frage diese als hilfreich empfand und sie als akzeptierte Antwort markierte? :) Aber im Ernst, Sie haben das Problem bereits selbst identifiziert: Viele der anderen zeitgenössischen Antworten schlugen hackige Lösungen vor, die in einem Produktionssystem unklug wären. (
Beachten
37

Kandidat für den kreativsten Missbrauch eines Linux-Befehls:

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

Wenn yourprogbesteht aus:

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

dann yourprog.outkönnte es so aussehen:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

Dies zeigt ein ziemlich gutes Maß an Präzision.

Hier ist eine Erklärung der Teile des Befehls:

  • nohup- Dadurch wird verhindert, dass der darauf folgende Befehl watchbeim Beenden des Terminals beendet wird.
  • watch- Dieses Programm führt einen Befehl wiederholt aus. Normalerweise wird jedes Mal, wenn der Befehl ausgeführt wird, der erste Bildschirm mit der Ausgabe des Befehls angezeigt watch.
  • -n 30- Das Intervall, in dem der Befehl ausgeführt werden soll. In diesem Fall ist es alle dreißig Sekunden.
  • --precise- Ohne diese Option wird watchder Befehl nach Intervallsekunden ausgeführt . Damit beginnt, wenn möglich , jeder Start des Befehls in dem Intervall. Wenn diese Option im Beispiel nicht angegeben wurde, werden die Zeiten aufgrund der zum Starten und Ausführen des Befehls ( yourprog) erforderlichen Zeit immer später um mehr als 30 Sekunden erhöht .
  • yourprog- Das watchauszuführende Programm oder die auszuführende Befehlszeile . 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 Wert größer als leitet die Ausgabe des Befehls, der von ausgeführt wird, watchin eine Datei um /dev/null. Diese Datei löscht alle darauf geschriebenen Daten. Auf diese Weise wird verhindert, dass die Ausgabe auf den Bildschirm geschrieben oder, da nohupsie verwendet wird, an eine aufgerufene Datei gesendet wird nohup.out.
  • &- Der watchBefehl wird im Hintergrund ausgeführt und die Steuerung wird an das Terminal oder den übergeordneten Prozess zurückgegeben.

Beachten Sie, dass nohupdie Umleitung der Ausgabe und der &Hintergrundsteuerungsoperator nicht spezifisch sind watch.

Hier ist eine Erklärung des Beispielskripts yourprog:

  • date- Gibt das aktuelle Datum und / oder die aktuelle Uhrzeit aus. Es kann sie auch einstellen.
  • +%M.%S.%N- Dies gibt das Ausgabeformat datean, das verwendet werden soll. %Mist die aktuelle Minute, %Sist die aktuelle Sekunde und %Nist die aktuelle Nanosekunde.
  • >> yourprog.out- Dadurch wird die Ausgabe des dateBefehls in eine aufgerufene Datei umgeleitet yourprog.out. Das Doppelte größer als bewirkt, dass die Ausgabe bei jedem Aufruf an die Datei angehängt wird, anstatt dass der vorherige Inhalt überschrieben wird.

Bearbeiten :

Möglicherweise könnten auch System-Timer missbraucht werden (oder es ist eine legitime Verwendung).

Siehe systemd / Timer als Cron-Ersatz und Cron-gegen-Systemd-Timer .

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

Dennis Williamson
quelle
6
Ich gebe +1 für reine Wange
Matt Simmons
2
Wäre schön mit dieser Antwort ein bisschen mehr Erklärung zu haben. Der Befehl nohup ist neu für mich. Das Internet sagt mir, es ist das Auflegen-Signal zu ignorieren. Was mich immer noch verwirrt.
donquixote
2
@donquixote: Es ist wichtig zu erkennen, dass der Befehl als Ganzes in meiner Antwort nicht empfohlen wird, daher die Verwendung des Wortes "Missbrauch". Um die Dinge für Sie ein wenig zu klären, da es nützliche Techniken gibt, werde ich versuchen, einige zu beschreiben. Das &bewirkt , dass der Befehl im Hintergrund laufen zu lassen, prompt sofort die Kontrolle an den Befehl zurückkehrt. Die Verwendung des nohupBefehls bewirkt, dass der Hintergrundprozess (in diesem Fall watch) das Aufhängesignal ignoriert, das gesendet wird, wenn die Shell beendet wird, z. B. wenn Sie das Terminal schließen. ...
Dennis Williamson
1
... Die Umleitung der Ausgabe mit >/dev/nullbewirkt , dass die Ausgabe verworfen wird, und verhindert, dass eine nohup.outDatei erstellt wird, die andernfalls erstellt würde, wenn die Standardausgabe ein Terminal ist.
Dennis Williamson
1
@donquixote: Nicht nur in 30 Sekunden, sondern alle 30 Sekunden. Der Rest ist, es unbeaufsichtigt im Hintergrund laufen zu lassen, um cron-ähnlicher zu sein. Wenn Sie verwenden sleepmöchten, müssen Sie eine Schleife schreiben, damit sich der Vorgang wiederholt ( watchwird dies für Sie ebenso wiederholt cron). Du würdest noch nohupund brauchen &. Ein zusätzliches Problem sleepwäre die Zeitverschiebung. Die --preciseOption von watchvermeidet dies. Ohne oder bei Verwendung sleepin einer Schleife wird dem Zeitintervall die Zeit hinzugefügt, die für die Ausführung der Befehle oder des Skripts erforderlich ist, damit jeder Lauf später und später als der ...
Dennis Williamson
13

Cron ist so konzipiert, dass es in jeder Minute aufwacht. Daher ist es nicht möglich, es ohne Hacking zu tun, zum Beispiel mit dem von Ihnen erwähnten Schlaf.

Balázs Pozsár
quelle
10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

Vergessen Sie nicht, etwas in Ihr Programm zu schreiben, damit es beendet wird, wenn bereits eine frühere Instanz ausgeführt wird.

#!/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

Dies lässt natürlich immer noch eine sehr kleine Chance für ein Scheitern. Suchen Sie daher bei Google nach einer besseren Lösung für Ihre Umgebung.

ghoti
quelle
es wurde gefragt:without a sleep command
philippe
10
Anderen Besuchern ist es egal, ob der Befehl sleep verwendet wird :)
donquixote
8

Sie können dies mit Software von Drittanbietern tun.

Eine Option, die für mich gut funktioniert hat, ist frequent-cron

Es erlaubt Millisekundengenauigkeit und gibt Ihnen die Möglichkeit, die nächste Ausführung aufzuschieben, bis die aktuelle beendet ist.

dieser juan
quelle
1
Frequent-Cron hat auch bei uns gut funktioniert und treibt viele unserer Produktionssysteme an. Wir hatten noch nie ein Problem damit.
Homer6
2

Ich hätte ein paar Bedenken:

(1) Manchmal ist ein System ausgelastet und kann die Dinge nicht genau zum 30-Sekunden-Zeitpunkt starten. Es ist dann möglich, dass zur gleichen Zeit, in der Sie einen Job ausführen, ein anderer Job auftaucht und dann 2 (oder mehr) Jobs dasselbe tun Ding. Je nach Skript kann es hier zu erheblichen Störungen kommen. Daher sollte die Codierung in einem solchen Skript Code enthalten, um sicherzustellen, dass nur eine Instanz des angegebenen Skripts gleichzeitig ausgeführt wird.

(2) Das Skript kann möglicherweise viel Aufwand verursachen und mehr Systemressourcen verbrauchen, als Sie möchten. Dies ist der Fall, wenn Sie gegen viele andere Systemaktivitäten antreten.

In diesem Fall würde ich ernsthaft in Erwägung ziehen, einen Daemon mit zusätzlichen Prozessen einzurichten, um sicherzustellen, dass er weiterhin ausgeführt wird, wenn er für Ihren Betrieb von entscheidender Bedeutung ist.

mdpc
quelle
1

Meine einfachste und beliebteste 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

  • Durch die Verwendung des flockBefehls wird vermieden, dass das Skript von mehreren Instanzen gleichzeitig ausgeführt wird. Dies kann in den meisten Fällen sehr wichtig sein.
  • flockund watch-Befehle sind bei den meisten Linux-Installationen verfügbar

Nachteile

  • Das Anhalten dieser Art von "Service" erfordert zwei Schritte
    • Kommentieren Sie den Cron-Eintrag aus
    • Töte das Skript oder den watchBefehl
asvany
quelle
2
Kann jemand dies einem Linux-Neuling erklären - mit Vor- und Nachteilen? Vielen Dank ..
a20
@asvany Ich denke, ich mag diese Lösung, aber als a20, könntest du bitte eine Erklärung für das "grüne" Linux posten? ty.
JoelAZ
0

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

  1. Holen Sie sich die Startzeit und merken Sie sie sich.
  2. Wenn eine Sperrdatei vorhanden ist, die Sie später berühren werden, und das Skript 60 Sekunden lang nicht ausgeführt wurde, warten Sie eine Sekunde und wiederholen Sie die Überprüfung. (zB während / schlafen) *
  3. Wenn die Sperrdatei nach Ablauf von 60 Sekunden noch vorhanden ist, beenden Sie sie mit einer veralteten Sperrwarnung.
  4. Touch-Lock-Datei.
  5. Während das Skript 60 Sekunden lang nicht ausgeführt wurde, wiederholen Sie Ihre eigentliche Aufgabe mit der gewünschten Ruhezeit.
  6. Sperrdatei löschen.
  7. Als Cron hinzufügen.
  8. Bob ist Dein Onkel.

Weniger Kopfschmerzen als das Erstellen und Überwachen eines Daemons.

* Wenn Sie PHP verwenden, merken Sie sich clearstatcache ().

Jemand
quelle