Chcę wykonywać skrypt powłoki dosłownie co 3 dni. Używanie crontab z 01 00 */3 * *
tak naprawdę nie spełnia warunku, ponieważ działałoby 31, a następnie ponownie pierwszego dnia miesiąca. */3
Składnia jest taka sama jak mówią 1,4,7 ... 25,28,31.
Powinny istnieć sposoby, aby sam skrypt sprawdził warunki i zakończył działanie, jeśli nie minęły 3 dni. Więc crontab wykonuje skrypt codziennie, ale sam skrypt sprawdzi, czy minęły 3 dni.
Znalazłem nawet trochę kodu, ale dał mi błąd składniowy, każda pomoc byłaby mile widziana.
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
źródło
źródło
*/3
nie działa „jeśli nie minęły 3 dni”: trzy dni od czego? Proszę edytować swoje pytanie i wyjaśnienia.date("z") % 3 == 0
cierpiałoby na podobny problem: warunek będzie fałszywy przez cztery dni między 29 grudnia a 3 stycznia, chyba że grudzień był rokiem przestępnym.Odpowiedzi:
Aby natychmiast przerwać wykonywanie skryptu i wyjść z niego, jeśli ostatnie wykonanie nie było jeszcze w określonym momencie, możesz użyć tej metody, która wymaga zewnętrznego pliku, który przechowuje datę i godzinę ostatniego wykonania.
Dodaj następujące wiersze u góry skryptu Bash:
Nie zapomnij ustawić znaczącej wartości jako
datefile=
i dostosować wartośćseconds=
do swoich potrzeb ($((60*60*24*3))
szacuje się na 3 dni).Jeśli nie chcesz osobnego pliku, możesz również zapisać czas ostatniego wykonania w znaczniku czasu modyfikacji skryptu. Oznacza to jednak, że wprowadzenie jakichkolwiek zmian w pliku skryptu spowoduje zresetowanie licznika 3 i będzie traktowane tak, jakby skrypt działał poprawnie.
Aby to zaimplementować, dodaj poniższy fragment kodu na górze pliku skryptu:
Ponownie nie zapomnij dostosować wartości
seconds=
do swoich potrzeb ($((60*60*24*3))
ocenia do 3 dni).źródło
$[ $(date +%s) - $(< lastrun) ]
. Jeśli skrypt jest uruchamiany z crona raz dziennie, mogę dodać trochę luzu do wymaganego przedziału czasowego, aby jeśli wykonanie skryptu opóźniło się o kilka sekund, następnym razem nie pominie całego dnia. To jest sprawdzanie każdego dnia, czy 71 godzin minęło.Cron jest naprawdę niewłaściwym narzędziem do tego. Jest rzeczywiście powszechnie stosowane i underloved narzędzie o nazwie na które działają siły. at został zaprojektowany głównie do użytku interaktywnego i jestem pewien, że ktoś znalazłby lepszy sposób na zrobienie tego.
W moim przypadku skrypt, który uruchamiam, powinien znajdować się na liście w testjobs.txt i zawierać wiersz, który czyta.
Jako przykład chciałbym mieć to jako testjobs.txt
Mam dwa niewinne polecenia, które mogą być twoimi skryptami. Uruchomiam echo, aby upewnić się, że mam wynik deterministyczny, i datę, aby potwierdzić, że polecenie zostanie uruchomione w razie potrzeby. Po uruchomieniu tej komendy at zakończy działanie, dodając nowe zadanie do at na 3 dni. (Testowałem z jedną minutą - co działa)
Jestem prawie pewien, że zostanę wezwany ze względu na sposób, w jaki byłem nadużywany, ale jest to przydatne narzędzie do planowania uruchomienia polecenia w czasie lub x dni po poprzednim poleceniu.
źródło
at
wydaje się tutaj lepszym podejściem. Problem z tym podejściem polega na tym, że za każdym razem, gdy ręcznie uruchamiasz skrypt, dodajesz kolejny zestaw zadań co 3 dniat
.at
jest na górze, lub potencjalnie znacznie więcej, jeśliat
jest blisko dolnej części skryptu o długim wykonaniu)Po pierwsze, powyższy fragment kodu jest niepoprawną składnią Bash, wygląda jak Perl. Po drugie,
z
parametrdate
powodujący wyświetlanie numerycznej strefy czasowej.+%j
to numer dnia. Potrzebujesz:Ale pod koniec roku nadal będziesz widział dziwność:
Możesz mieć więcej szczęścia z utrzymywaniem liczby w pliku i testowaniem / aktualizowaniem tego.
źródło
date()
wbudowanej funkcji, ale wygląda to trochę jak date () w PHP (gdziez
jest „Dzień roku (od 0)”)Jeśli możesz po prostu pozostawić skrypt działający bez końca, możesz:
Ta pętla jest zawsze prawdziwa, więc zawsze wykona kod, a następnie zaczeka trzy dni przed ponownym uruchomieniem pętli.
źródło
while true
?at
rozwiązanie będzie dryfować według czasu wykonania skryptu przy każdym uruchomieniu. Oczywiście można to obejść, oszczędzając czas, kiedy skrypt zaczyna się i śpi, do 3 dni od tego.Możesz użyć anakronu zamiast crona, jest on zaprojektowany dokładnie do robienia tego, czego potrzebujesz. Z strony podręcznika:
źródło