Ok, also habe ich 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?
Ich habe auch gelesen, dass cron nicht das beste Werkzeug ist, wenn ich es so oft starte. Gibt es ein anderes besseres Werkzeug, das ich verwenden oder auf Ubuntu 11.04 installieren kann, das eine bessere Option ist? Gibt es eine Möglichkeit, den obigen Cron zu reparieren?
Sie haben */30
im Minuten Bezeichner - das bedeutet jede Minute, jedoch einen Schritt von 30 (dh jede halbe Stunde). Da cron
nicht auf unterminute Auflösungen reduziert wird, müssen Sie einen anderen Weg finden.
Eine Möglichkeit, obwohl es ein bisschen kludge ist, besteht darin, zwei Jobs zu haben, einer um 30 Sekunden versetzt:
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Beide cron - Jobs laufen tatsächlich jede Minute, aber der letztere wartet eine halbe Minute, bevor er das "Fleisch" des Jobs ausführt, /path/to/executable
.
Du kannst nicht Cron hat eine 60 Sekunden lange Granularität.
* * * * * 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'\''
Die Granularität von Cron ist in Minuten und war nicht entworfen, um alle x
Sekunden aufzuwachen, um etwas auszuführen. Führen Sie Ihre sich wiederholende Aufgabe innerhalb 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
Es sind keine zwei Cron-Einträge erforderlich.
* * * * * /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'\''"
Sie können meine Antwort auf diese ähnliche Frage prüfen
Grundsätzlich habe ich dort ein Bash-Skript namens "runEvery.sh" eingefügt, das Sie jede Minute mit cron ausführen und als Argumente den echten Befehl, den Sie ausführen möchten, und die Häufigkeit in Sekunden übergeben, in der Sie ihn ausführen möchten.
etwas wie das
* * * * * ~/bin/runEvery.sh 5 myScript.sh
Cron-Job kann nicht verwendet werden, um einen Job im Sekundenintervall einzuplanen. Sie können einen Cron-Job nicht alle 5 Sekunden ausführen. Alternativ können Sie ein Shell-Skript schreiben, das den Befehl sleep 5
verwendet.
Erstellen Sie alle -5-seconds.sh ein Shell-Skript mit bash while-Schleife (siehe unten).
$ cat every-5-seconds.sh
#!/bin/bash
while true
do
/home/ramesh/backup.sh
sleep 5
done
Führen Sie nun dieses Shell-Skript im Hintergrund mit Nohup
aus (siehe unten). Dadurch wird das Skript auch nach dem Abmelden von der Sitzung ausgeführt. Dadurch wird Ihr backup.sh-Shell-Skript alle 5 Sekunden ausgeführt.
$ Nohup ./every-5-seconds.sh &
Verwenden Sie die Uhr:
$ watch --interval .30 script_to_run_every_30_sec.sh
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
Verwenden Sie fcron ( http://fcron.free.fr/ ) - gibt Ihnen Granularität in Sekunden und viel besser und reichhaltiger als cron (vixie-cron) und stabil. Ich habe dumme Sachen gemacht, etwa 60 PHP-Skripte auf einem Rechner in sehr dummen Einstellungen laufen zu lassen, und es hat trotzdem seine Arbeit gemacht!
Wenn Sie ein aktuelles Linux-Betriebssystem mit SystemD ausführen, können Sie die Einheit SystemD Timer verwenden, um Ihr Skript auf einer beliebigen Granularitätsstufe (theoretisch bis auf Nanosekunden) auszuführen. Wenn Sie möchten, können Sie flexiblere Startregeln festlegen, als es Cron jemals erlaubt hätte . Nein sleep
klickt erforderlich
Es ist etwas mehr als nur eine Zeile in einer Cron-Datei einzurichten, aber wenn Sie etwas Besseres als "Every Minute" benötigen, lohnt sich der Aufwand.
Das SystemD-Timermodell ist im Wesentlichen das - Timer sind Einheiten, die nach Ablauf eines Timers Serviceeinheiten starten.
Für jedes Skript/Befehl, das Sie einplanen möchten, müssen Sie eine Serviceeinheit und dann eine zusätzliche Zeiteinheit haben. Eine einzelne Timereinheit kann mehrere Zeitpläne enthalten, so dass 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 (in /etc/systemd/system
, wie oben beschrieben, für eine systemweite Einstellung oder bei ~/.config/systemd/user
für ein benutzerspezifisches Setup), müssen Sie den Timer (nicht den Dienst) aktivieren, indem Sie systemctl enable helloworld.timer
ausführen. Wenn Sie den Timer sofort starten möchten (anstatt darauf zu warten, dass er nach einem Neustart startet), führen Sie auch systemctl start helloworld.timer
aus.
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 wie ein Cron-Job verhält.AccuracySec
- Legt die Genauigkeit des Timers fest. Timer sind nur so genau, wie dieses Feld eingestellt ist, und der Standardwert ist 1 Minute (emuliert Cron). Der Hauptgrund dafür, die beste Genauigkeit nicht zu fordern, ist die Verbesserung des Stromverbrauchs. Wenn SystemD den nächsten Lauf so planen kann, dass er mit anderen Ereignissen übereinstimmt, muss die CPU weniger oft geweckt werden. Der 1ms
im obigen Beispiel ist nicht ideal - ich setze die Genauigkeit für 1
(1 Sekunde) normalerweise in meinen untergeordneten Minutenaufträgen ein, aber das würde bedeuten, dass Sie, wenn Sie sich das Protokoll ansehen, das die "Hello World" -Meldungen anzeigt Sehen Sie, dass es oft um 1 Sekunde zu spät kommt. Wenn Sie damit einverstanden sind, schlage ich vor, die Genauigkeit auf 1 Sekunde oder mehr einzustellen.Wie Sie vielleicht bemerkt haben, ahmt dieser Timer Cron nicht allzu gut nach - in dem Sinne, dass der Befehl nicht am Beginn jeder Wanduhrperiode beginnt (dh er beginnt nicht bei der 10. Sekunde der Uhr, dann die 20 und so weiter). Stattdessen passiert einfach, wenn der Timer ellipsen wird. Wenn das System um 12:05:37 bootete, wird der Befehl das nächste Mal um 12:05:47 ausgeführt, dann um 12:05:57 usw. Wenn Sie sich für die Genauigkeit der Wanduhr interessieren, können Sie dies tun möchten die Felder OnBootSec
und OnUnitActiveSec
ersetzen und stattdessen eine OnCalendar
-Regel mit dem gewünschten Zeitplan festlegen (der meines Wissens nach im Kalenderformat nicht schneller als 1 Sekunde sein kann). Das obige Beispiel kann auch geschrieben werden als:
OnCalendar=*-*-* *:*:00,10,20,30,40,50
Letzter Hinweis: Wie Sie wahrscheinlich schon vermutet haben, startet die Einheit helloworld.timer
die Einheit helloworld.service
, da sie denselben Namen haben (ohne das Suffix der Einheitstypen). Dies ist die Standardeinstellung, die Sie jedoch überschreiben können, indem Sie das Feld Unit
für den Abschnitt [Timer]
festlegen.
Weitere Einzelheiten finden Sie unter:
man systemd.timer
man systemd.time
man systemd.service
man system.exec
Mit Crontab-Jobs können Sie einen Job in Minuten/Stunden/Tagen einplanen, 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 -e
und eine crontab, um dieses Skript auszuführen:
* * * * * /home/test/30sec.sh > /dev/null
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 Zeitaufteilung im Skript. Deshalb habe ich alle 20 Sekunden (dreimal pro Minute) ein Skript ausgeführt. 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
Schauen Sie sich frequent-cron an - es ist alt, aber sehr stabil und Sie können auf Mikrosekunden zurückgreifen. Zum jetzigen Zeitpunkt würde ich nur sagen, dass ich immer noch versuche, herauszufinden, wie ich es außerhalb von init.d, aber als systemeigener Dienst, installieren soll. Bis Ubuntu 18 läuft es jedoch nur Fein noch mit init.d (Abstand kann bei letzteren Versionen variieren). Es hat den zusätzlichen Vorteil (?), Dass sichergestellt wird, dass keine weitere Instanz des Skripts PHP erzeugt wird, wenn keine vorherige abgeschlossen wurde, wodurch potenzielle Probleme mit Speicherverlusten verringert werden.
Ich hatte gerade eine ähnliche Aufgabe und wählte den folgenden Ansatz:
Nohup watch -n30 "kill -3 NODE_PID" &
Ich musste einige 30 Sekunden alle 30 Sekunden einen periodischen Kill -3 (um die Stack-Spur eines Programms zu erhalten) haben.
Nohup ... &
Dies ist hier, um sicherzugehen, dass ich die Ausführung der Überwachung nicht verliere, wenn ich die Shell verliere (Netzwerkproblem, Windows-Absturz usw.).
schreiben Sie ein Shell-Skript create .sh-Datei
nano every30second.sh
und schreibe ein Skript
#!/bin/bash
For (( i=1; i <= 2; i++ ))
do
write Command here
sleep 30
done
dann setze cron für dieses Skript crontab -e
(* * * * * /home/username/every30second.sh)
diese Cron-Aufruf-SH-Datei wird alle 1 Minute ausgeführt und im Befehl .sh-Datei wird 2 Mal 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 für folgende Schleife: For (( i=1; i <= 12; i++ ))
wenn Sie für eine Sekunde auswählen, berechnen Sie 60/Sekunde und schreiben Sie in For-Schleife
Derzeit verwende ich die untenstehende Methode. Funktioniert ohne Probleme.
* * * * * /bin/bash -c ' for i in {1..X}; do YOUR_COMMANDS ; sleep Y ; done '
Wenn Sie alleNSekunden ausführen möchten, istX 60/N undYN.
Vielen Dank.