Ich möchte buchstäblich alle 3 Tage ein Shell-Skript ausführen. Die Verwendung von crontab mit 01 00 */3 * *
erfüllt die Bedingung nicht wirklich, da es am 31. und dann wieder am 1. Tag eines Monats ausgeführt wird. Die */3
Syntax entspricht der von 1,4,7 ... 25,28,31.
Es sollte Möglichkeiten geben, das Skript selbst dazu zu bringen, die Bedingungen zu überprüfen und zu beenden, wenn 3 Tage nicht vergangen sind. Crontab führt das Skript also jeden Tag aus, aber das Skript selbst prüft, ob 3 Tage vergangen sind.
Ich habe sogar Code gefunden, aber es gab mir Syntaxfehler, jede Hilfe wäre dankbar.
if (! (date("z") % 3)) {
exit;
}
main.sh: line 1: syntax error near unexpected token `"z"'
main.sh: line 1: `if (! (date("z") % 3)) {'
command-line
bash
scripts
cron
Taavi
quelle
quelle
*/3
nicht "wenn 3 Tage nicht vergangen sind": drei Tage seit was? Bitte bearbeiten Sie Ihre Frage und klären Sie.date("z") % 3 == 0
würde unter einem ähnlichen Problem leiden: Die Bedingung wird für die vier Tage zwischen dem 29. Dezember und dem 3. Januar falsch sein, es sei denn, dieser Dezember war Teil eines Schaltjahres.Antworten:
Um ein Skript sofort abzubrechen und zu beenden, wenn die letzte Ausführung noch nicht mindestens eine bestimmte Zeit zurückliegt, können Sie diese Methode verwenden, für die eine externe Datei erforderlich ist, in der das Datum und die Uhrzeit der letzten Ausführung gespeichert sind.
Fügen Sie diese Zeilen oben in Ihr Bash-Skript ein:
Vergessen Sie nicht, einen aussagekräftigen Wert als
datefile=
festzulegen und den Wertseconds=
an Ihre Bedürfnisse anzupassen ($((60*60*24*3))
ausgewertet auf 3 Tage).Wenn Sie keine separate Datei möchten, können Sie die letzte Ausführungszeit auch im Änderungszeitstempel Ihres Skripts speichern. Das bedeutet jedoch, dass Änderungen an Ihrer Skriptdatei den 3-Zähler zurücksetzen und so behandelt werden, als ob das Skript erfolgreich ausgeführt wurde.
Um dies zu implementieren, fügen Sie das folgende Snippet oben in Ihre Skriptdatei ein:
Vergessen Sie auch hier nicht, den Wert von
seconds=
an Ihre Bedürfnisse anzupassen (ergibt$((60*60*24*3))
3 Tage).quelle
$[ $(date +%s) - $(< lastrun) ]
. Wenn das Skript einmal am Tag von cron ausgeführt wird, kann es sein, dass das erforderliche Zeitintervall etwas langsamer wird, sodass das nächste Mal keinen ganzen Tag überspringt, wenn sich die Ausführung des Skripts um einige Sekunden verzögert. Das ist jeden Tag zu überprüfen, ob 71 Stunden vergangen sind.Cron ist wirklich das falsche Werkzeug dafür. Es gibt tatsächlich ein häufig verwendetes und underloved Tool namens an der Macht zu arbeiten. at ist hauptsächlich für den interaktiven Gebrauch konzipiert und ich bin sicher, dass jemand einen besseren Weg finden würde, dies zu tun.
In meinem Fall würde ich das Skript, das ich ausführe, in testjobs.txt auflisten und eine Zeile einfügen, die lautet.
Als Beispiel hätte ich dies als testjobs.txt
Ich habe zwei unschuldige Befehle, die Ihre Muscheln sein könnten. Ich führe Echo aus, um sicherzustellen, dass ich eine deterministische Ausgabe habe, und Datum, um zu bestätigen, dass der Befehl nach Bedarf ausgeführt wird. Wenn at diesen Befehl ausführt, wird es beendet, indem 3 Tage lang ein neuer Job zu at hinzugefügt wird. (Ich habe mit einer Minute getestet - was funktioniert)
Ich bin mir ziemlich sicher, dass ich wegen der Art und Weise, wie ich missbraucht habe, gerufen werde, aber es ist ein praktisches Tool, um einen Befehl so zu planen, dass er zu einem Zeitpunkt oder x Tage nach einem vorherigen Befehl ausgeführt wird.
quelle
at
hier der bessere Ansatz zu sein scheint. Das Problem bei diesem Ansatz ist, dass Sie jedes Mal, wenn Sie das Skript manuell ausführen, einen weiteren Satz vonat
Aufgaben für jeden dritten Tag hinzufügen .at
es oben ist, oder möglicherweise viel mehr, wennat
es sich in der Nähe des unteren Randes eines Skripts mit langer Ausführung befindet)Erstens ist das obige Codefragment eine ungültige Bash-Syntax und sieht aus wie Perl. Zweitens bewirkt der
z
Parameter,date
dass er die numerische Zeitzone ausgibt.+%j
ist die Tagesnummer. Du brauchst:Aber zum Jahresende werden Sie immer noch Fremdheit erleben:
Möglicherweise haben Sie besseres Glück, wenn Sie eine Zählung in einer Datei führen und diese testen / aktualisieren.
quelle
date()
eingebaute Funktion, aber das sieht ein bisschen aus wie date () in PHP (woz
ist "Der Tag des Jahres (ab 0)")Wenn Sie das Skript einfach ständig laufen lassen können, können Sie Folgendes tun:
Diese Schleife ist immer wahr, führt also immer den Code aus und wartet dann drei Tage, bevor die Schleife erneut gestartet wird.
quelle
while true
?at
Lösung wird dies bei jedem Lauf um die Ausführungszeit des Skripts verschoben. Dies kann natürlich umgangen werden, indem Sie die Zeit sparen, in der das Skript gestartet wird, und bis zu 3 Tage schlafen.Sie können Anacron anstelle von Cron verwenden. Es ist genau darauf ausgelegt, das zu tun, was Sie brauchen. Aus der Manpage:
quelle