Alle 30 Sekunden einen Cron ausführen


313

Ok, ich habe einen Cron, den ich alle 30 Sekunden laufen muss.

Folgendes habe ich:

*/30 * * * * /bin/bash -l -c 'cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'''

Es läuft, aber läuft das alle 30 Minuten oder 30 Sekunden?

Außerdem habe ich gelesen, dass Cron möglicherweise nicht das beste Werkzeug ist, wenn ich es so oft ausführe. Gibt es ein anderes besseres Tool, das ich unter Ubuntu 11.04 verwenden oder installieren kann und das eine bessere Option ist? Gibt es eine Möglichkeit, den oben genannten Cron zu reparieren?


CommaToast, und was passiert, wenn Ihre Javascript- oder Java-App aus irgendeinem Grund umfällt und beendet wird? Wie wird es neu gestartet? :-)
paxdiablo

12
Füge eine kleine NodeJS-App hinzu, lol. Warum nicht eine kleine C ++ App? Während wir gerade dabei sind, können wir es "cron" nennen und es als Dienst ausführen.
Andrew


Ich habe dies gerade beim Betrachten von Benutzerprofilen gefunden und festgestellt, dass Sie vor weniger als einer Stunde online waren (nur um zu überprüfen, ob das Konto noch verwendet wird). Gibt es einen bestimmten Grund, warum Sie keine der folgenden Antworten akzeptiert haben?
Fabian N.

Antworten:


731

Sie haben */30in der Minutenangabe - das heißt jede Minute, aber mit einem Schritt von 30 (mit anderen Worten, jede halbe Stunde). Da crones sich nicht um Auflösungen von weniger als einer Minute handelt, müssen Sie einen anderen Weg finden.

Eine Möglichkeit, obwohl es ein bisschen kludge (a) ist , besteht darin, zwei Jobs zu haben, von denen einer um 30 Sekunden versetzt ist:

# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * *              /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )

Sie werden sehen, dass ich Kommentare hinzugefügt und formatiert habe, um sicherzustellen, dass sie einfach synchronisiert werden können.

Beide cronJobs werden tatsächlich jede Minute ausgeführt, aber der letztere wartet eine halbe Minute, bevor er das "Fleisch" des Jobs ausführt /path/to/executable.

Weitere (nicht cronbasierte) Optionen finden Sie in den anderen Antworten hier, insbesondere in den Erwähnungen fcronund systemd. Diese sind wahrscheinlich vorzuziehen, vorausgesetzt, Ihr System kann sie verwenden (z. B. Installation fcronoder Installation einer Distribution systemd).


Wenn Sie die kludgy-Lösung nicht verwenden möchten, können Sie eine schleifenbasierte Lösung mit einer kleinen Änderung verwenden. Sie müssen immer noch verwalten, dass Ihr Prozess in irgendeiner Form ausgeführt wird, aber sobald dies sortiert ist, sollte das folgende Skript funktionieren:

#!/bin/env bash

# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.

((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done

while true; do
    # Start a background timer BEFORE the payload runs.

    sleep 30 &

    # Execute the payload, some random duration up to the limit.
    # Extra blank line if excess payload.

    ((delay = RANDOM % maxtime + 1))
    ((maxtime += 1))
    echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
    [[ ${delay} -gt 30 ]] && echo
    sleep ${delay}

    # Wait for timer to finish before next cycle.

    wait
done

Der Trick besteht darin, ein sleep 30Aber zu verwenden, um es im Hintergrund zu starten, bevor Ihre Nutzdaten ausgeführt werden. Warten Sie nach Abschluss der Nutzdaten einfach, bis der Hintergrund sleepfertig ist.

Wenn die Nutzlast nSekunden dauert (wo n <= 30), beträgt die Wartezeit nach der Nutzlast 30 - nSekunden. Wenn es länger als 30 Sekunden dauert, wird der nächste Zyklus verzögert, bis die Nutzlast fertig ist, jedoch nicht mehr.

Sie werden sehen, dass ich dort Debug-Code habe, der an einer Minute beginnt, damit die Ausgabe zunächst leichter zu verfolgen ist. Ich erhöhe auch schrittweise die maximale Nutzlastzeit, damit die Nutzlast möglicherweise die 30-Sekunden-Zykluszeit überschreitet (eine zusätzliche Leerzeile wird ausgegeben, damit der Effekt offensichtlich ist).

Es folgt ein Probelauf (wobei die Zyklen normalerweise 30 Sekunden nach dem vorherigen Zyklus beginnen):

Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).

Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).

Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).

Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).

Wenn Sie die klobige Lösung vermeiden möchten, ist dies wahrscheinlich besser. Sie benötigen noch einen cronJob (oder einen gleichwertigen Job), um regelmäßig zu erkennen, ob dieses Skript ausgeführt wird, und wenn nicht, starten Sie es. Das Skript selbst übernimmt dann das Timing.


(a) Einige meiner Arbeitskollegen würden sagen, dass Kludges meine Spezialität sind :-)


29
Dies ist eine großartige Problemumgehung, so sehr, dass ich denke, es geht über die Kludginess hinaus
Fragezeichen

14
@ rubo77, nur wenn es weniger als eine Sekunde dauerte :-) Wenn es 29 Sekunden dauerte, würde es um 0:00:00, 0: 00.59, 0:01:00, 0:01:59 und so weiter passieren .
Paxdiablo

1
Super hinterhältig, sehr kreativ!
K Raphael

2
Was sind die runden Klammern um die zweite Zeile?
Nigel Alderton

2
Dies ist eine schöne Lösung für ein Problem, das ansonsten die Effektivität von Cron für bestimmte Aufgaben beeinträchtigt, die in Bruchteilen von Minuten ausgeführt werden müssen. Vielen Dank.
Fiddy Bux

67

Das kannst du nicht. Cron hat eine Granularität von 60 Sekunden.

* * * * * cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''
* * * * * sleep 30 && cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''

Entspricht diese Syntax der von paxdiablo? Oder gibt es subtile Unterschiede?
Nicolas Raoul

Der Unterschied ist: Ich habe den ursprünglichen Pfad zur Binärdatei verwendet. @paxdiablo verwendete eine Art Metasyntax. (und ruft eine Unterschale auf)
Wildplasser

1
Ich meinte, &&anstelle von ( ; ).
Nicolas Raoul

2
Es tut uns leid. Nein, es gibt einen Unterschied. Der &&Bediener schließt kurz, sodass der nächste Befehl in der Kette nicht ausgeführt wird, wenn der vorherige fehlgeschlagen ist.
Wildplasser

Diese Granularität sollte für eine Auflösung von weniger als einer Minute kein Problem darstellen.
Juan Isaza

37

Die Granularität von Cron ist in Minuten angegeben und wurde nicht entwickelt, um alle xSekunden aufzuwachen und etwas auszuführen. Führen Sie Ihre sich wiederholende Aufgabe in einer Schleife aus und sie sollte das tun, was Sie brauchen:

#!/bin/env bash
while [ true ]; do
 sleep 30
 # do what you need to here
done

54
Denken Sie daran, dass das nicht ganz dasselbe ist. Wenn der Job beispielsweise 25 Sekunden dauert, wird er alle 55 Sekunden und nicht alle 30 Sekunden gestartet. Es spielt vielleicht keine Rolle, aber Sie sollten sich der möglichen Konsequenzen bewusst sein.
Paxdiablo

7
Sie können den Job im Hintergrund ausführen, dann wird er in fast genau 30 Sekunden ausgeführt.
Chris Koston

1
während [wahr] schlafen 30 # tun, was Sie hier tun müssen --------- getan sollte in kleinem Fall sein
Tempel

1
Wird es nicht dazu führen, while [ true ]dass Sie viele Instanzen desselben Skripts haben, da cron jede Minute eine neue startet?
Carcamano

2
Sie können tun, sleep $remainingTimewo die verbleibende Zeit 30 minus der Zeit ist, die der Job benötigt hat (und sie auf Null begrenzen, wenn sie> 30 Sekunden dauert). Nehmen Sie sich also die Zeit vor und nach der eigentlichen Arbeit und berechnen Sie die Differenz.
Mahemoff

32

Wenn Sie ein aktuelles Linux-Betriebssystem mit SystemD ausführen, können Sie die SystemD-Timer-Einheit verwenden, um Ihr Skript mit einer beliebigen Granularitätsstufe (theoretisch bis zu Nanosekunden) und - falls gewünscht - flexibleren Startregeln auszuführen, als Cron es jemals zugelassen hat . Keine sleepKludges erforderlich

Das Einrichten dauert etwas länger als eine einzelne Zeile in einer Cron-Datei. Wenn Sie jedoch etwas Besseres als "Jede Minute" benötigen, lohnt sich die Mühe.

Das SystemD-Timer-Modell lautet im Wesentlichen wie folgt: Timer sind Einheiten, die Serviceeinheiten starten, wenn ein Timer abgelaufen ist .

Für jedes Skript / jeden Befehl, den Sie planen möchten, müssen Sie eine Serviceeinheit und dann eine zusätzliche Timereinheit haben. Eine einzelne Timer-Einheit kann mehrere Zeitpläne enthalten, sodass Sie normalerweise nicht mehr als einen Timer und einen Dienst benötigen.

Hier ist ein einfaches Beispiel, das alle 10 Sekunden "Hello World" protokolliert:

/etc/systemd/system/helloworld.service::

[Unit]
Description=Say Hello
[Service]
ExecStart=/usr/bin/logger -i Hello World

/etc/systemd/system/helloworld.timer::

[Unit]
Description=Say Hello every 10 seconds
[Timer]
OnBootSec=10
OnUnitActiveSec=10
AccuracySec=1ms
[Install]
WantedBy=timers.target

Nach dem Einrichten dieser Einheiten ( /etc/systemd/systemwie oben beschrieben für eine systemweite Einstellung oder ~/.config/systemd/userfür eine benutzerspezifische Einrichtung) müssen Sie den Timer (jedoch nicht den Dienst) durch Ausführen aktivieren systemctl enable --now helloworld.timer(das --nowFlag startet auch den Timer) Sofort, andernfalls wird es erst nach dem nächsten Start oder der Benutzeranmeldung gestartet.

Die hier verwendeten [Timer]Abschnittsfelder lauten wie folgt:

  • OnBootSec - Starten Sie den Dienst so viele Sekunden nach jedem Start.
  • OnUnitActiveSec- Starten Sie den Dienst so viele Sekunden nach dem letzten Start des Dienstes. Dies führt dazu, dass sich der Timer wiederholt und sich wie ein Cron-Job verhält.
  • AccuracySec- stellt die Genauigkeit des Timers ein. Timer sind nur so genau wie in diesem Feld festgelegt, und der Standardwert ist 1 Minute (emuliert cron). Der Hauptgrund dafür, nicht die beste Genauigkeit zu fordern, ist die Verbesserung des Stromverbrauchs. Wenn SystemD den nächsten Lauf so planen kann, dass er mit anderen Ereignissen zusammenfällt, muss die CPU seltener geweckt werden. Das 1msim obigen Beispiel ist nicht ideal - ich setze die Genauigkeit 1in meinen geplanten Sub-Minute-Jobs normalerweise auf (1 Sekunde), aber das würde bedeuten, dass Sie das sehen würden, wenn Sie sich das Protokoll mit den Nachrichten "Hallo Welt" ansehen es ist oft um 1 Sekunde zu spät. Wenn Sie damit einverstanden sind, empfehle ich, die Genauigkeit auf 1 Sekunde oder mehr einzustellen.

Wie Sie vielleicht bemerkt haben, ahmt dieser Timer Cron nicht so gut nach - in dem Sinne, dass der Befehl nicht zu Beginn jeder Wanduhrperiode startet (dh nicht in der 10. Sekunde der Uhr startet). dann der 20. und so weiter). Stattdessen passiert es nur, wenn der Timer abläuft. Wenn das System um 12:05:37 gestartet wurde, erfolgt die nächste Ausführung des Befehls um 12:05:47, dann um 12:05:57 usw. Wenn Sie an der tatsächlichen Genauigkeit der Wanduhr interessiert sind, können Sie dies tun wollen die ersetzen OnBootSecund OnUnitActiveSecFelder und stattdessen eine set - OnCalendarRegel mit dem Zeitplan , die Sie wollen (was soweit ich verstehe nicht schneller sein kann als 1 Sekunde, mit dem Kalenderformat). Das obige Beispiel kann auch wie folgt geschrieben werden:

OnCalendar=*-*-* *:*:00,10,20,30,40,50

Letzte Anmerkung: Wie Sie wahrscheinlich vermutet haben, helloworld.timerstartet das helloworld.serviceGerät das Gerät, weil es denselben Namen hat (abzüglich des Suffixes für den Einheitentyp). Dies ist die Standardeinstellung, aber Sie können diese überschreiben, indem Sie das UnitFeld für den [Timer]Abschnitt festlegen.

Weitere wichtige Details finden Sie unter:


2
Ich finde oft bessere Antworten wie diese im Kommentarbereich. IMHO, obwohl Cron ein Grundnahrungsmittel für geplante Jobs war, sollte diese Antwort die akzeptierte sein, da es sich nicht um einen "Hack-Job" für Schlaf handelt und das Risiko einer Parallelisierung der Ausführung lang laufender Aufgaben unter Berücksichtigung des erforderlichen Intervalls / der erforderlichen Häufigkeit besteht
Qiqo,

2
Hervorragende Antwort, sollte die ausgewählte Antwort sein
GuidedHacking

21

Es sind keine zwei Cron-Einträge erforderlich. Sie können sie in einen mit folgenden Elementen einfügen:

* * * * * /bin/bash -l -c "/path/to/executable; sleep 30 ; /path/to/executable"

also in deinem Fall:

* * * * * /bin/bash -l -c "cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'' ; sleep 30 ; cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''"


11
Hinweis: Dies wird nur korrekt ausgeführt, wenn die Ausführung des Skripts weniger als eine Sekunde dauert
rubo77

2
Rubo - Wenn der Auftrag Sekunden dauert (anstelle von Milli- oder Mikrosekunden), wird er nicht alle dreißig Sekunden ausgeführt, um zweimal pro Minute ausgeführt werden zu können. Beginnen Sie also mit 30 und subtrahieren Sie dann die ungefähre Anzahl von Sekunden pro Lauf, wenn diese größer als 1 Sekunde ist.
Andrew

2
Dies hilft auch nicht, wenn Sie Fehlerberichte für jeden Lauf separat erhalten möchten.
Joeln

joelin - der Befehl, den ich gebe, verhindert nicht das Abrufen von Protokoll- oder Ausgabedaten. Ich habe den Befehl vereinfacht, um die Frage zu beantworten. Um die Protokollierung zu erfassen, kann / sollte jeder Befehl eine umgeleitete Ausgabe haben, wenn Sie eine Protokollierung benötigen, z. B. Skript / Rails Runner -e Produktion '\' 'Song.insert_latest' \ '' könnte als Skript / Rails Runner -e Produktion '\' geschrieben werden 'Song.insert_latest' \ '' 2> & 1> / path_to_logfile und kann erneut für jeden Befehl innerhalb des einzelnen Cron-Eintrags ausgeführt werden.
Andrew

13

Sie können meine Antwort auf diese ähnliche Frage überprüfen

Grundsätzlich habe ich dort ein Bash-Skript mit dem Namen "runEvery.sh" eingefügt, das Sie alle 1 Minute mit cron ausführen und als Argumente den tatsächlichen Befehl übergeben können, den Sie ausführen möchten, und die Häufigkeit in Sekunden, in der Sie ihn ausführen möchten.

etwas wie das

* * * * * ~/bin/runEvery.sh 5 myScript.sh


10

Verwenden Sie die Uhr:

$ watch --interval .30 script_to_run_every_30_sec.sh

kann ich so etwas benutzen $ watch --interval .10 php some_file.php? oder watchfunktioniert nur mit .sh-Dateien?
Yevhenii Shashkov

Sie können alles mit Uhr laufen lassen. Das Intervall liegt jedoch zwischen dem Ende und dem Beginn des nächsten Befehls und wird daher --interval .30nicht zweimal pro Minute ausgeführt. Dh watch -n 2 "sleep 1 && date +%s"es wird alle 3s erhöht.
Jmartori

Bitte beachten Sie, dass watches für die Verwendung im Terminal konzipiert wurde. Obwohl es ohne Terminal (mit nohupanschließender Abmeldung ausgeführt) oder mit einem gefälschten Terminal (z. B. screen) funktionieren kann , bietet es keine Vorteile für Cron-ähnliches Verhalten, z. B. Wiederherstellung nach einem Fehler. Neustart nach dem Booten usw. '.
Guss

9

Der Cron-Job kann nicht verwendet werden, um einen Job im Sekundenintervall zu planen. dh Sie können nicht planen, dass ein Cron-Job alle 5 Sekunden ausgeführt wird. Die Alternative besteht darin, ein Shell-Skript zu schreiben, das darin sleep 5Befehle verwendet .

Erstellen Sie alle fünf Sekunden ein Shell-Skript mit der bash while-Schleife, wie unten gezeigt.

$ cat every-5-seconds.sh
#!/bin/bash
while true
do
 /home/ramesh/backup.sh
 sleep 5
done

Führen Sie dieses Shell-Skript nun im Hintergrund nohupwie unten gezeigt aus. Dadurch wird das Skript auch nach dem Abmelden von Ihrer Sitzung weiter ausgeführt. Dadurch wird Ihr Shell-Skript backup.sh alle 5 Sekunden ausgeführt.

$ nohup ./every-5-seconds.sh &

4
Die Zeit wird driften. Wenn backup.shdie Ausführung beispielsweise 1,5 Sekunden dauert, wird sie alle 6,5 Sekunden ausgeführt. Es gibt Möglichkeiten, dies zu vermeiden, zum Beispielsleep $((5 - $(date +%s) % 5))
Keith Thompson

Ich bin neu bei nohup. Während Sie Ihr Beispiel ausführen, gibt nohup "keine solche Datei oder kein solches Verzeichnis" zurück. Nach einigen Suchanfragen scheinen Sie 'sh' nach nohup verpasst zu haben. So: $ nohup sh ./every-5-seconds.sh &
VHanded

6

Verwenden Sie fcron ( http://fcron.free.fr/ ) - bietet Ihnen Granularität in Sekunden und viel besser und funktionsreicher als cron (vixie-cron) und auch stabil. Früher habe ich dumme Dinge gemacht, wie etwa 60 PHP-Skripte auf einem Computer in sehr dummen Einstellungen laufen zu lassen, und es hat immer noch seinen Job gemacht!


1
Geständnisse eines PHP-Entwicklers; )
Eric Kigathi

3
Eigentlich Geständnisse eines Systemingenieurs, der PHP-Entwicklern ermöglicht .... :)
Adi Chiru

6

in dir /etc/cron.d/

neu eine Datei erstellen excute_per_30s

* * * * * yourusername  /bin/date >> /home/yourusername/temp/date.txt
* * * * * yourusername sleep 30; /bin/date >> /home/yourusername/temp/date.txt

wird alle 30 Sekunden cron ausgeführt


4

Derzeit verwende ich die folgende Methode. Funktioniert ohne Probleme.

* * * * * /bin/bash -c ' for i in {1..X}; do YOUR_COMMANDS ; sleep Y ; done '

Wenn Sie alle ausführen möchten N Sekunden , dann X wird 60 / N und Y wird N .

Danke dir.


Sie wollen wahrscheinlich ändern YOUR_COMMANDSzu YOUR_COMMANDS &, so dass der Befehl in den Hintergrund gestartet wird, andernfalls , wenn der Befehl mehr als ein Bruchteil einer Sekunde dauert - es wird den nächsten Start verzögern. Wenn also bei X = 2 und Y = 30 der Befehl 10 Sekunden dauert, wird er in der Minute und dann 40 Sekunden später anstelle von 30 gestartet. Kudus an @paxdiablo.
Guss

Wenn ich den /bin/bash -cTeil (einschließlich der Anführungszeichen) weglasse, wird das Skript aus irgendeinem Grund nur jede Minute ausgeführt, wobei die Iteration (in meinem Fall X=12und Y=5) ignoriert wird .
Abiyi

3

Mit dem Crontab-Job kann ein Job in Minuten / Stunden / Tagen geplant werden, jedoch nicht in Sekunden. Die Alternative :

Erstellen Sie ein Skript, das alle 30 Sekunden ausgeführt wird:

#!/bin/bash
# 30sec.sh

for COUNT in `seq 29` ; do
  cp /application/tmp/* /home/test
  sleep 30
done

Verwenden Sie crontab -eund eine Crontab, um dieses Skript auszuführen:

* * * * * /home/test/30sec.sh > /dev/null

2
Wenn ich das richtig verstehe, wird dieses Skript 30 Mal ausgeführt und wartet zwischen jeder Iteration 30 Sekunden. Wie ist es sinnvoll, es jede Minute in Cron auszuführen?
FuzzyAmi

2

Sie können dieses Skript als Dienst ausführen und alle 30 Sekunden neu starten

Registrieren Sie einen Dienst

sudo vim /etc/systemd/system/YOUR_SERVICE_NAME.service

Fügen Sie den folgenden Befehl ein

Description=GIVE_YOUR_SERVICE_A_DESCRIPTION

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=simple
ExecStart=YOUR_COMMAND_HERE
Restart=always
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

Dienste neu laden

sudo systemctl daemon-reload

Aktivieren Sie den Dienst

sudo systemctl enable YOUR_SERVICE_NAME

Starten Sie den Dienst

sudo systemctl start YOUR_SERVICE_NAME

Überprüfen Sie den Status Ihres Dienstes

systemctl status YOUR_SERVICE_NAME

1

Danke für all die guten Antworten. Um es einfach zu machen, mochte ich die gemischte Lösung mit der Steuerung von crontab und der Zeitteilung im Skript. Das habe ich getan, um alle 20 Sekunden (dreimal pro Minute) ein Skript auszuführen. Crontab-Linie:

 * * * * 1-6 ./a/b/checkAgendaScript >> /home/a/b/cronlogs/checkAgenda.log

Skript:

cd /home/a/b/checkAgenda

java -jar checkAgenda.jar
sleep 20
java -jar checkAgenda.jar 
sleep 20
java -jar checkAgenda.jar 

Was bedeutet 1-6?
Phantom007

@ Phantom007 1-6 steht für Montag bis Samstag, wobei "-" ein Bereich und "0" Sonntag ist. Hier ist ein guter Link, der alle Felder sehr gut erklärt und wo Sie es testen können: " crontab.guru/# * _ * _ * _ * _ 1-6"
jfajunior

1

Schreiben Sie ein Shell-Skript. Erstellen Sie eine .sh-Datei

nano alle 30 Sekunden

und Skript schreiben

#!/bin/bash
For  (( i=1; i <= 2; i++ ))
do
    write Command here
    sleep 30
done

Setzen Sie dann cron für dieses Skript crontab -e

(* * * * * /home/username/every30second.sh)

Diese Cron-Aufruf-SH-Datei wird alle 1 Minute und im Befehl .sh-Datei zweimal in 1 Minute ausgeführt

Wenn Sie das Skript 5 Sekunden lang ausführen möchten, ersetzen Sie 30 durch 5 und ändern Sie die Schleife wie folgt: For (( i=1; i <= 12; i++ ))

Wenn Sie für eine Sekunde auswählen, berechnen Sie 60 / Ihre Sekunde und schreiben Sie in die For-Schleife


0

Ich hatte gerade eine ähnliche Aufgabe zu erledigen und den folgenden Ansatz zu verwenden:

nohup watch -n30 "kill -3 NODE_PID" &

Ich musste mehrere Stunden lang alle 30 Sekunden einen periodischen Kill -3 ausführen (um die Stapelverfolgung eines Programms zu erhalten).

nohup ... & 

Dies ist hier, um sicherzugehen, dass ich die Ausführung der Uhr nicht verliere, wenn ich die Shell verliere (Netzwerkproblem, Windows-Absturz usw.)


0

Schauen Sie sich Frequent-Cron an - es ist alt, aber sehr stabil und Sie können auf Mikrosekunden zurückgreifen. Zu diesem Zeitpunkt würde ich nur dagegen sagen, dass ich immer noch versuche, herauszufinden, wie man es außerhalb von init.d installiert, aber als nativer systemd-Dienst, aber bis Ubuntu 18 läuft es sicher nur gut noch mit init.d (Abstand kann bei letzteren Versionen variieren). Es hat den zusätzlichen Vorteil (?), Dass sichergestellt wird, dass keine weitere Instanz des PHP-Skripts erzeugt wird, es sei denn, eine vorherige Instanz wurde abgeschlossen, wodurch potenzielle Probleme mit Speicherverlusten verringert werden.


-1

In einer Shell-Schleife ausführen, Beispiel:

#!/bin/sh    
counter=1
while true ; do
 echo $counter
 counter=$((counter+1))
 if [[ "$counter" -eq 60 ]]; then
  counter=0
 fi
 wget -q http://localhost/tool/heartbeat/ -O - > /dev/null 2>&1 &
 sleep 1
done

Selbst wenn 60dies a sein sollte 30, möchten Sie dies möglicherweise wget in die ifAnweisung verschieben, da es sonst jede Sekunde ausgeführt wird. Auf jeden Fall bin ich mir nicht sicher, wie das besser ist als nur eine einzige sleep 30. Wenn Sie die tatsächliche UNIX-Zeit und nicht Ihren Zähler überwachen würden, würde dies einen Unterschied machen.
Paxdiablo

Wenn Sie den Zählerausdruck wiederholen, können Sie die durch EXCUTE COMMAND verzögerte Zeit ermitteln, wenn Sie wget NICHT im Hintergrund ausführen.
Lo Vega
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.