Ich brauche eine Reihe von Befehlen oder einen einzelnen Befehl, der schläft, bis das nächste Mal eine bestimmte Zeit wie „4:00“ eintritt.
Wie würde ich das machen?
Der at
Befehl oder ein Cronjob kommt nicht in Frage, da ich das Skript, in dem ich mich gerade befinde, nicht verlassen darf.
Der spezielle Fall, von dem ich spreche, ist ein Skript, das auf dem Bildschirm ausgeführt wird. Es ist sehr wichtig, dass ich die Ausführung des Skripts nicht durch das Skript selbst stoppe, da viele wichtige Variablen gespeichert sind, die an einem bestimmten Punkt des Skripts benötigt werden. Das Skript soll nicht immer regelmäßig ausgeführt werden. Es muss nur zu einem bestimmten Zeitpunkt ausgeführt werden.
Es wäre sehr vorteilhaft, wenn das Skript keine Dateien oder andere Aufgaben wie Cronjobs oder andere Screens erstellen müsste. Dies ist einfach eine Frage des Designs.
Ich hatte gerade eine tolle Idee:
difference=$(($(date -d "4:00" +%s) - $(date +%s)))
if [ $difference -lt 0 ]
then
sleep $((86400 + difference))
else
sleep $difference
fi
Habt ihr bessere Ideen?
Weitere Informationen werden auf Wunsch ergänzt!
Antwort1
Terdons Vorschlag würde funktionieren, aber ich denke, meiner ist effizienter.
difference=$(($(date -d "4:00" +%s) - $(date +%s)))
if [ $difference -lt 0 ]
then
sleep $((86400 + difference))
else
sleep $difference
fi
Hiermit wird die Differenz zwischen der angegebenen Zeit und der aktuellen Zeit in Sekunden berechnet. Wenn die Zahl negativ ist, müssen wir die Sekunden für einen ganzen Tag (86400 um genau zu sein) addieren, um die Sekunden zu erhalten, die wir zum Schlafen haben. Wenn die Zahl positiv ist, können wir sie einfach verwenden.
Antwort2
Vorausgesetzt, es handelt sich um ein Shell-Skript, sollte Folgendes funktionieren:
while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done
Dies gilt für 24-Stunden-Zeiten. Wenn Sie möchten, dass dies sowohl um 4:00 Uhr als auch um 16:00 Uhr fortgesetzt wird, verwenden Sie stattdessen Folgendes:
while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done
Antwort3
AnOpenBSD, könnte man mit folgendem einen */5
5-minütigencrontab(5)
Job in einen 00
stündlichen Job (um sicherzustellen, dass weniger E-Mails generiert werden und gleichzeitig die gleiche Aufgabe in exakten Abständen ausgeführt wird):
#!/bin/sh -x
for k in $(jot 12 00 55)
do
echo $(date) doing stuff
sleep $(expr $(date -j +%s $(printf %02d $(expr $k + 5))) - $(date -j +%s))
done
Notiere dass derdate(1)
würde auch brechen diesleep(1)
per Design bei der letzten Iteration, da 60
Minuten keine gültige Zeitangabe sind (es sei denn, sie sind es!), sodass wir nicht zusätzlich warten müssen, bevor wir unseren E-Mail-Bericht erhalten.
Beachten Sie auch, dass, sollte eine der Iterationen länger als die ihr zugewiesenen 5 Minuten dauern, dies sleep
ebenfalls konstruktionsbedingt fehlschlagen würde, indem überhaupt nicht geschlafen wird (aufgrund einer als Befehlszeilenoption interpretierten negativen Zahl, anstatt zur nächsten Stunde oder sogar Ewigkeit zu springen). Auf diese Weise wird sichergestellt, dass Ihr Auftrag dennoch innerhalb der zugewiesenen Stunde abgeschlossen werden kann (wenn beispielsweise nur eine der Iterationen ein wenig länger als 5 Minuten dauert, hätten wir noch Zeit, aufzuholen, ohne dass etwas zur nächsten Stunde springt).
Derprintf(1)
wird benötigt, da date
für die Minutenangabe genau zwei Ziffern erwartet werden.