it-swarm.com.de

Führen Sie das Bash-Skript buchstäblich alle 3 Tage aus

Ich möchte 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. eines Monats ausgeführt werden würde. Die Syntax von */3 entspricht der von 1,4,7 ... 25,28,31.

Es sollte Möglichkeiten geben, das Skript selbst zu veranlassen, die Bedingungen zu überprüfen und zu beenden, wenn 3 Tage nicht vergangen sind. Also führt crontab das Skript jeden Tag aus, aber das Skript selbst würde prüfen, ob 3 Tage vergangen sind.

Ich habe sogar etwas Code gefunden, aber es gab mir einen Syntaxfehler, für jede Hilfe wäre ich dankbar.

if (! (date("z") % 3)) {
     exit;
}

main.sh: line 1: syntax error near unexpected token `"z"'
main.sh: line 1: `if (! (date("z") % 3)) {'
8
Taavi

Um ein Skript sofort abzubrechen und zu beenden, wenn die letzte Ausführung noch nicht vor einem bestimmten Zeitpunkt stattgefunden hat, 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:

#!/bin/bash

# File that stores the last execution date in plain text:
datefile=/path/to/your/datefile

# Minimum delay between two script executions, in seconds. 
seconds=$((60*60*24*3))

# Test if datefile exists and compare the difference between the stored date 
# and now with the given minimum delay in seconds. 
# Exit with error code 1 if the minimum delay is not exceeded yet.
if test -f "$datefile" ; then
    if test "$(($(date "+%s")-$(date -f "$datefile" "+%s")))" -lt "$seconds" ; then
        echo "This script may not yet be started again."
        exit 1
    fi
fi

# Store the current date and time in datefile
date -R > "$datefile"

# Insert your normal script here:

Vergessen Sie nicht, einen aussagekräftigen Wert als datefile= festzulegen und den Wert von seconds= an Ihre Bedürfnisse anzupassen ($((60*60*24*3)) wird auf 3 Tage ausgewertet).


Wenn Sie keine separate Datei wünschen, können Sie auch die letzte Ausführungszeit im Änderungszeitstempel Ihres Skripts speichern. Das bedeutet jedoch, dass das Vornehmen von Änderungen an Ihrer Skriptdatei den Zähler 3 zurücksetzt und so behandelt wird, als ob das Skript erfolgreich ausgeführt wurde.

Fügen Sie dazu das folgende Snippet oben in Ihre Skriptdatei ein:

#!/bin/bash

# Minimum delay between two script executions, in seconds. 
seconds=$((60*60*24*3))

# Compare the difference between this script's modification time stamp 
# and the current date with the given minimum delay in seconds. 
# Exit with error code 1 if the minimum delay is not exceeded yet.
if test "$(($(date "+%s")-$(date -r "$0" "+%s")))" -lt "$seconds" ; then
    echo "This script may not yet be started again."
    exit 1
fi

# Store the current date as modification time stamp of this script file
touch -m -- "$0"

# Insert your normal script here:

Vergessen Sie auch hier nicht, den Wert von seconds= an Ihre Bedürfnisse anzupassen ($((60*60*24*3)) ergibt 3 Tage).

12
Byte Commander

Cron ist dafür wirklich das falsche Werkzeug. Es gibt tatsächlich ein allgemein verwendetes und geliebtes Tool namens at , das möglicherweise funktioniert. ats ist hauptsächlich für den interaktiven Gebrauch gedacht 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 der Datei testjobs.txt auflisten und eine Zeile einfügen, die lautet.

Als Beispiel hätte ich dies als testjobs.txt

echo "cat" >> foo.txt
date >> foo.txt
at now + 3 days < testjobs.txt

Ich habe zwei unschuldige Befehle, die Ihre Muschelskripte sein könnten. Ich führe Echo aus, um sicherzustellen, dass ich eine deterministische Ausgabe habe, und ein Datum, um zu bestätigen, dass der Befehl nach Bedarf ausgeführt wird. Wenn at diesen Befehl ausführt, wird er 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, die ich missbraucht habe, gerufen werde, aber es ist ein praktisches Tool, um die Ausführung eines Befehls um um eine Zeit oder x Tage nach einem vorherigen Befehl.

12
Journeyman Geek

Erstens ist das obige Codefragment eine ungültige Bash-Syntax, sieht aus wie Perl. Zweitens bewirkt der Parameter z bis date, dass die numerische Zeitzone ausgegeben wird. +%j ist die Tageszahl. Du brauchst:

if [[ ! $(( $(date +%j) % 3 )) ]] ;then
     exit
fi

Aber zum Jahresende werden Sie immer noch Seltsamkeiten feststellen:

$ for i in 364 365  1 ; do echo "Day $i, $(( $i % 3 ))"; done
Day 364, 1
Day 365, 2
Day 1, 1

Vielleicht haben Sie mehr Glück, wenn Sie eine Zählung in einer Datei führen und diese testen/aktualisieren.

3
waltinator

Wenn Sie das Skript einfach immer laufen lassen können, können Sie Folgendes tun:

while true; do

[inert code here]

sleep 259200
done

Diese Schleife ist immer wahr, führt also immer den Code aus und wartet dann drei Tage, bevor die Schleife erneut gestartet wird.

2
mkingsbu

Sie können Anacron anstelle von Cron verwenden. Es wurde genau dafür entwickelt, das zu tun, was Sie benötigen. Aus der Manpage:

Mit Anacron können Befehle in regelmäßigen Abständen ausgeführt werden, wobei die Häufigkeit in Tagen angegeben wird. Anders als bei cron (8) wird nicht davon ausgegangen, dass die Maschine ununterbrochen läuft. Daher kann es auf Computern verwendet werden, die nicht rund um die Uhr ausgeführt werden, um tägliche, wöchentliche und monatliche Jobs zu steuern, die normalerweise von cron gesteuert werden.

Bei der Ausführung liest Anacron eine Liste von Jobs aus einer Konfigurationsdatei, normalerweise/etc/anacrontab (siehe anacrontab (5)). Diese Datei enthält die Liste der Jobs, die Anacron steuert. Jeder Auftragseintrag gibt einen Zeitraum in Tagen, eine Verzögerung in Minuten, eine eindeutige Auftragskennung und einen Shell-Befehl an.

Anacron prüft für jeden Job, ob dieser Job in den letzten n Tagen ausgeführt wurde, wobei n der für diesen Job angegebene Zeitraum ist. Andernfalls führt Anacron den Shell-Befehl des Jobs aus, nachdem die als Verzögerungsparameter angegebene Anzahl von Minuten abgewartet wurde.

Nachdem der Befehl beendet wurde, zeichnet Anacron das Datum in einer speziellen Zeitstempeldatei für diesen Job auf, damit er weiß, wann er erneut ausgeführt werden muss. Für die Zeitberechnung wird nur das Datum verwendet. Die Stunde wird nicht verwendet.

2
Twinkles