Masz */30
w specyfikatorze minut - to znaczy co minutę, ale z krokiem 30 (innymi słowy co pół godziny). Ponieważ cron
nie sprowadza się to do rozdzielczości poniżej minuty, musisz znaleźć inną drogę.
Jedną z możliwości, choć jest to trochę kludge (a) , jest posiadanie dwóch zadań, jedno przesunięte o 30 sekund:
# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Zobaczysz, że dodałem komentarze i sformatowałem je, aby zapewnić łatwą synchronizację.
Oba cron
zadania faktycznie uruchomić każdą minutę, ale ten ostatni z nich będzie czekać pół minuty przed wykonaniem „mięso” zadania, /path/to/executable
.
W przypadku innych ( cron
nieopartych na opcjach) opcji zobacz inne odpowiedzi tutaj, szczególnie te, które wspominają fcron
i systemd
. Prawdopodobnie są one preferowane przy założeniu, że Twój system ma możliwość ich używania (na przykład instalowania fcron
lub posiadania dystrybucji systemd
).
Jeśli nie chcesz używać rozwiązania kludgy, możesz użyć rozwiązania opartego na pętli z niewielką modyfikacją. Nadal będziesz musiał zarządzać utrzymywaniem procesu w jakiejś formie, ale po posortowaniu następujący skrypt powinien działać:
#!/bin/env bash
# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.
((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done
while true; do
# Start a background timer BEFORE the payload runs.
sleep 30 &
# Execute the payload, some random duration up to the limit.
# Extra blank line if excess payload.
((delay = RANDOM % maxtime + 1))
((maxtime += 1))
echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
[[ ${delay} -gt 30 ]] && echo
sleep ${delay}
# Wait for timer to finish before next cycle.
wait
done
Sztuką jest użycie przycisku sleep 30
ale, aby uruchomić go w tle przed uruchomieniem ładunku. Następnie po zakończeniu ładunku wystarczy poczekać na zakończenie tła sleep
.
Jeśli ładunek zajmuje n
sekundy (gdzie n <= 30
), wówczas oczekiwanie po ładunku wynosi 30 - n
sekundy. Jeśli zajmie to więcej niż 30 sekund, następny cykl zostanie opóźniony, aż ładunek się skończy, ale już nie.
Zobaczysz, że mam tam kod debugowania, aby rozpocząć od jednominutowej granicy, aby początkowo łatwiej było śledzić dane wyjściowe. Stopniowo zwiększam również maksymalny czas ładunku, aby w końcu zobaczysz, że ładunek przekracza 30 sekundowy cykl (generowany jest dodatkowy pusty wiersz, więc efekt jest oczywisty).
Następuje przebieg próbny (gdzie cykle zwykle rozpoczynają się 30 sekund po poprzednim cyklu):
Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).
Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).
Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).
Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).
Jeśli chcesz uniknąć niechlujnego rozwiązania, prawdopodobnie jest to lepsze. Nadal będziesz potrzebować cron
zadania (lub odpowiednika), aby okresowo wykrywać, czy ten skrypt jest uruchomiony, a jeśli nie, uruchom go. Ale sam skrypt obsługuje czas.
(a) Niektórzy z moich kolegów z pracy powiedzieliby, że kludges to moja specjalność :-)