Śpij do następnego wystąpienia określonego czasu


11

Potrzebuję serii poleceń lub pojedynczego polecenia, które śpi aż do następnego wystąpienia określonego czasu, takiego jak „4:00”.

Jak mam to zrobić?

atPolecenie lub zadanie crona nie jest opcją, bo nie musi opuścić skrypt jestem obecnie.

Konkretny przypadek, o którym mówię, to skrypt działający na ekranie. Bardzo ważne jest, aby nie przerywać wykonywania skryptu przez sam skrypt, ponieważ istnieje wiele ważnych zmiennych, które są potrzebne w pewnym momencie skryptu. Skrypt nie zawsze powinien być wykonywany regularnie. Musi zostać wykonany w określonym czasie.

Byłoby bardzo szkodliwe, gdyby skrypt musiał utworzyć jakiekolwiek pliki lub inne zadania, takie jak cronjobs lub inne ekrany. To po prostu kwestia projektu.

Właśnie miałem niesamowity pomysł:

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

Czy masz jakieś lepsze pomysły?

Więcej informacji zostanie dodanych na żądanie!


Czy mógłbyś wyjaśnić nieco swoje pytanie? Co masz na myśli, mówiąc: „Nie wolno mi opuszczać scenariusza, w którym aktualnie jestem”
sebelk,

Co powiesz na sprawdzenie skryptu pod kątem istnienia pliku „wake up” i uśpienie przez pewien czas przed ponownym sprawdzeniem? Następnie możesz użyć crona do utworzenia pliku, wykorzystując niezawodność crona, ale możesz też mieć swój długowieczny skrypt. Wystarczy, że skrypt usunie plik „wake up”, gdy przestanie spać.
kurtm 10.10.2013

Zauważ, że na komputerze Mac należy wymienić date -dz date -ji zamienić 4:00z 0400.
pjvandehaar

Odpowiedzi:


17

Sugestia terdona zadziałałaby, ale chyba moja jest bardziej wydajna.

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

Oblicza różnicę między podanym czasem a bieżącym czasem w sekundach. Jeśli liczba jest ujemna, musimy dodać sekundy na cały dzień (dokładnie 86400), aby uzyskać sekundy, które musimy spać, a jeśli liczba jest dodatnia, możemy jej po prostu użyć.


Co się stanie, jeśli zegar systemowy przesunie się do przodu / do tyłu (np .: ntp).
WhyNotHugo

10

Zakładając, że jest to skrypt powłoki, powinno to działać:

while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done

To 24 godziny. Jeśli chcesz, aby trwało to zarówno o 4:00, jak i 16:00, użyj tego:

while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done

To może być opcja. Właśnie miałem pomysł. Wrócę za kilka minut.
BrainStone 10.10.2013

0

W OpenBSD można użyć następujących rzeczy do skompresowania */55-minutowego crontab(5)zadania do zadania 00godzinowego (aby upewnić się, że generowanych jest mniej wiadomości e-mail, a wszystkie wykonują to samo zadanie w dokładnych odstępach czasu):

#!/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

Pamiętaj, że przy ostatniej iteracji złamałoby date(1)to również sleep(1)projekt, ponieważ 60minuty nie są poprawnym czasem (chyba że tak!), Dlatego nie będziemy musieli czekać więcej czasu przed otrzymaniem naszego raportu e-mail.

Zwróć też uwagę, że jeśli jedna z iteracji zostanie poświęcona na więcej niż 5 minut, sleeprównież łaskawie zawiedzie z założenia, nie śpiąc wcale (z powodu liczby ujemnej interpretowanej jako opcja wiersza poleceń, zamiast owijania się w następnej godziny lub nawet wieczności), upewniając się w ten sposób, że twoja praca może zostać ukończona w wyznaczonej godzinie (np. jeśli tylko jedna z iteracji zajmie trochę więcej niż 5 minut, wtedy będziemy mieli czas na nadrobienie zaległości, bez wszystko zawija się do następnej godziny).

Jest printf(1)to konieczne, ponieważ dateoczekuje dokładnie dwóch cyfr dla specyfikacji minutowej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.