Muszę zacząć cronjob codziennie, ale godzinę później każdego dnia. To, co mam do tej pory, działa w przeważającej części, z wyjątkiem 1 dnia roku:
0 0 * * * sleep $((3600 * (10#$(date +\%j) \% 24))) && /usr/local/bin/myprog
Gdy dzień roku będzie równy 365, zadanie rozpocznie się o 5:00, ale następnego dnia (nie licząc roku przestępnego) dzień będzie miał wartość 1, więc zadanie rozpocznie się o 1:00. Jak mogę pozbyć się tej narożnej skrzynki?
Odpowiedzi:
Moim preferowanym rozwiązaniem byłoby uruchamianie zadania co godzinę, ale sam skrypt sprawdza, czy czas uruchomić, czy nie i kończy pracę bez robienia czegokolwiek 24 razy na 25.
crontab:
u góry
myprog
:Jeśli nie chcesz wprowadzać żadnych zmian w samym skrypcie, możesz również zaznaczyć pole „czas uruchomienia” we wpisie crontab, ale tworzy to długą, nieestetyczną linię:
źródło
date
wrócił z jądra, był1ms
wcześniejszy niż oczekiwany czas uruchomienia skryptu, sprawdzenie dałoby niepoprawny wynik.ntpd
to, stara się tylko zabić zegar, a nie przeskoczyć go, aby uniknąć tego rodzaju problemów, ale masz rację, to (lubntpdate
) czasami może przeskoczyć czas do tyłu. Jeśli chodzi ocron
błędne obliczenie opóźnienia snu, jestem pewien, że byłby to błąd! Mimo to, punkt rozważany, a obejściem byłoby zaplanowanie zadania 30 minut po godzinie, co jest mniej prawdopodobne, że spowoduje problem ... Lub dodaj ± 1800 w wyrażeniu arytmetycznym przed przyjęciem modemu 3600 reamainder.Jeśli system ma systemd, możesz do tego użyć zdarzeń liczników czasu. Po prostu zdefiniuj nową usługę , która powinna zawierać polecenie / zadanie, które chcesz wykonać, a następnie utwórz zdarzenie timera z
OnUnitActiveSec
opcją:Użyj tej samej nazwy dla plików, tyle że zamiast tego
.service
użyj.timer
.Synteza:
job.service
w/etc/systemd/system/
katalogu.systemctl status job.service
.job.timer
in/etc/systemd/system/
.Podaj wymagane informacje:
systemctl list-timers
źródło
Jeśli nie masz nic przeciwko użyciu czegoś innego niż cronjobs, sugerowałbym mniej znane narzędzie
at
. Po prostu napisz skrypt, który zaplanuje uruchomienie w ciągu 25 godzin, a następnie wywoła Twój program. To wydaje się być najczystszym rozwiązaniem.Na przykład możesz napisać to w ~ / script.sh:
A potem po prostu
bash ~/script.sh
raz uruchom .Dzięki @HalosGhost za pomysł zaplanowania zadania raz na 25 godzin.
źródło
at
do tego celu: (1) jeśli zadanie nie wykona się poprawnie nawet raz, prawdopodobnie również nie przełoży się ponownie, a następnie nie tylko następne wykonanie, ale wszystkie przyszłe wykonania zostaną skutecznie anulowane, dopóki człowiek nie zauważy, i (2) ponieważ zadanie zajmuje trochę niezerowego czasu, użycie naiwnegonow + 25 hours
oznacza, że będzie ono działać za kilka sekund (lub dłużej) za każdym razem, a jeśli to opóźnienie narasta z czasem, co ostatecznie powoduje, że działa całkowicie źle czas.at
jest ograniczona do minut i rozpoczyna wszystkie zadania o [czas]: 00.at
pracy pierwszą rzeczą w skrypcie na uniknięcie tych problemów. Niezależnie od tego, jeśli wystąpi błąd, cały łańcuch jest zepsuty, co może, ale nie musi być pożądane: jeśli przypadek użycia to „uruchom to tylko wtedy, gdy działa”, to nie restartowanie jest świetną funkcją. Ale jeśli przypadek użycia jest „zawsze uruchamiany, nawet jeśli ostatni nie powiódł się”,at
to nie jest właściwym narzędziem.