Czy mogę uruchomić zadanie CRON częściej niż co minutę?

44

Czy możliwe jest uruchamianie zadania cron co 30 sekund bez polecenia uśpienia?

użytkownik15336
źródło
4
Jaki masz zamiar? Czy cron jest odpowiednim narzędziem do tego celu?
Manuel Faux,
Dobre pytanie.
Preet Sangha
Na przykład obecnie używam crona do zmiany obrazu tła pulpitu, aby ominąć ograniczenia natywnego przełącznika obrazu tła (nie nurkując w podkatalogach). Gdybym chciał przełączać się częściej niż raz na minutę, wpadłbym na to ograniczenie cron. (chociaż natywny przełącznik bg ma te same ograniczenia)
donquixote

Odpowiedzi:

36

Jeśli twoje zadanie musi być uruchamiane tak często, cron jest niewłaściwym narzędziem. Oprócz tego, że po prostu nie będzie tak często uruchamiał zadań, ryzykujesz również poważne problemy, jeśli zadanie trwa dłużej niż przerwa między uruchomieniami. Przepisz swoje zadanie w celu demonizacji i trwałego działania, a następnie uruchom je z crona, jeśli to konieczne (upewniając się, że nie uruchomi się ponownie, jeśli już działa).

duskwuff
źródło
18
Część „ryzykujesz także poważnymi problemami, jeśli zadanie trwa dłużej niż przerwa między uruchomieniami”. nie jest prawdą, a gdyby tak było, dotyczyłoby to w równym stopniu zadań wykonanych co 5 minut, co godzinę lub co miesiąc. Ten problem ma rozwiązania (użycie pliku pid lub innego i sprawdzenie, czy zadanie jest już uruchomione przed jego uruchomieniem). Problem polega na tym, że cron po prostu nie zezwala na tę częstotliwość, ale błędem jest twierdzenie, że wykonanie zadania co mniej niż minutę jest z natury błędne.
matteo,
2
Miałem na myśli, jeśli nie używasz pliku pid. Jeśli Twoje zadanie jest uruchamiane co X minut i jego ukończenie zajmuje więcej niż X minut, skończysz na nakładaniu zadań. Jeśli twoje zadanie jest również ograniczone jakimś zasobem (procesor, przepustowość sieci / dysku itp.), To uruchamianie większej liczby zadań jednocześnie spowoduje, że ukończenie zajmie więcej czasu, a ostatecznie komputer zmieni się w druzgocący bałagan.
duskwuff
2
Możesz run-oneupewnić się, że program / nawet skrypt PHP nie uruchamia zduplikowanej instancji. sudo apt-get install run-onei nazwij torun-one <normal command>
kouton
3
Jak pokazują dalsze odpowiedzi, jest to bardzo możliwe, choć nieco hackerskie. Dlaczego robisz to źle? zaakceptowana odpowiedź tutaj, kiedy w ogóle nie odpowiada na pytanie?
Ktoś
@ Mantriur Ponieważ autor pytania uznał je za pomocne i oznaczył jako zaakceptowaną odpowiedź? :) Ale poważnie, sam już zidentyfikowałeś problem: wiele innych współczesnych odpowiedzi proponowało hackerskie rozwiązania, których nierozsądne byłoby zastosować w systemie produkcyjnym. (Należy również pamiętać, że kilka innych odpowiedzi pojawiło się dopiero po latach od pytania, więc nie były jeszcze dostępne do zaakceptowania!)
duskwuff
37

Kandydat na najbardziej twórcze niewłaściwe użycie polecenia Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Jeśli yourprogskłada się z:

date +%M.%S.%N >> yourprog.out

następnie yourprog.outmoże wyglądać następująco:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

wskazując na całkiem dobry poziom precyzji.

Oto wyjaśnienie części polecenia:

  • nohup- Dzięki temu polecenie, które następuje po nim, watchw tym przypadku, nie kończy pracy po wyjściu terminala.
  • watch- Ten program uruchamia polecenie wielokrotnie. Zwykle pierwszy ekran wyniku polecenia jest wyświetlany przy każdym watchuruchomieniu polecenia.
  • -n 30- Interwał uruchamiania polecenia. W tym przypadku co trzydzieści sekund.
  • --precise- Bez tej opcji watchuruchamia polecenie po upływie kilku sekund. Dzięki niemu każde uruchomienie polecenia rozpoczyna się w interwale, jeśli to możliwe. Gdyby ta opcja nie została podana w przykładzie, czasy byłyby coraz wyższe o ponad 30 sekund za każdym razem ze względu na czas potrzebny do uruchomienia i wykonania polecenia ( yourprog).
  • yourprog- Program lub wiersz poleceń watchdo wykonania. Jeśli wiersz poleceń zawiera znaki specjalne dla powłoki (np. Spację lub średnik), należy go zacytować.
  • >/dev/null- Im większy niż przekierowuje wyjściowe polecenia prowadzony przez watchdo pliku /dev/null. Plik ten odrzuca wszelkie zapisane na nim dane. Zapobiega to zapisywaniu danych wyjściowych na ekranie lub, ponieważ nohupjest używane, zapobiega wysyłaniu danych wyjściowych do pliku o nazwie nohup.out.
  • &- watchPolecenie jest uruchamiane w tle, a sterowanie jest zwracane do procesu terminalu lub procesu nadrzędnego.

Zauważ nohup, że przekierowanie wyjścia i &operator kontroli tła nie są specyficzne dla watch.

Oto wyjaśnienie przykładowego yourprogskryptu:

  • date- Wyświetla bieżącą datę i / lub godzinę. Może je również ustawić.
  • +%M.%S.%N- Określa format wyjściowy datedo użycia. %Mjest bieżącą minutą, %Sjest bieżącą sekundą i %Njest bieżącą nanosekundą.
  • >> yourprog.out- To przekierowuje wyjście datepolecenia do pliku o nazwie yourprog.out. Podwójne większe niż powoduje, że dane wyjściowe są dołączane do pliku przy każdym wywołaniu, a nie poprzednia treść jest zastępowana.

Edytuj :

Być może inną rzeczą, która może być nadużywana (a może jest to zgodne z prawem) jest systemowy.

Zobacz systemd / Timers jako zamiennik crona i Cron vs systemd timery .

Postaram się wkrótce opublikować przykład.

Dennis Williamson
źródło
6
Daję +1 za czysty policzek
Matt Simmons,
2
Byłoby miło mieć trochę więcej wyjaśnień z tą odpowiedzią. Polecenie nohup jest dla mnie nowe. Internet mówi mi, że należy zignorować sygnał rozłączenia. Co wciąż sprawia, że ​​jestem zdezorientowany.
donquixote
2
@donquixote: Ważne jest, aby uznać, że polecenie jako całość w mojej odpowiedzi nie jest zalecaną rzeczą, stąd użycie słowa „niewłaściwe użycie”. Jednak, aby wyjaśnić wam trochę, ponieważ są zawarte przydatne techniki, postaram się opisać kilka. &Powoduje polecenie, aby uruchomić w tle, powracając do natychmiastowego kontrolę wiersza polecenia. Użycie nohuppolecenia powoduje, że proces w tle (w tym przypadku watch) ignoruje sygnał zawieszenia, który jest wysyłany po wyjściu powłoki, na przykład po zamknięciu terminala. ...
Dennis Williamson
1
... Przekierowanie wyjścia za pomocą >/dev/nullpowoduje, że dane wyjściowe są odrzucane i zapobiega tworzeniu nohup.outpliku, który w innym przypadku zostałby utworzony, gdy standardowe wyjście jest terminalem.
Dennis Williamson,
1
@donquixote: Nie tylko 30 sekund od teraz, co 30 sekund. Reszta polega na tym, aby działał bez nadzoru w tle, aby był bardziej podobny do crona. Jeśli chcesz użyć sleep, musisz napisać pętlę, aby proces się powtórzył ( watchrobi to za ciebie, jak to robi cron). Nadal będziesz potrzebować nohupi &. Dodatkowym problemem sleepmoże być przesunięcie czasu. --preciseOpcja watchunika tego. Bez niego lub podczas używania sleepw pętli odstęp czasu ma czas potrzebny na uruchomienie poleceń lub skryptu, więc każde uruchomienie jest późniejsze i późniejsze niż ...
Dennis Williamson
13

Cron jest zaprojektowany tak, aby budził się o każdej minucie, więc nie można tego zrobić bez hakowania, na przykład snu, jak wspomniałeś.

Balázs Pozsár
źródło
10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

Nie zapomnij napisać czegoś do swojego programu, aby wyjść, jeśli poprzednia instancja już działa.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Oczywiście nadal pozostawia to bardzo małą szansę na awarię, więc wyszukaj w Google lepsze rozwiązanie odpowiednie dla twojego środowiska.

ghoti
źródło
zapytano:without a sleep command
philippe
10
Inni użytkownicy, którzy znajdą to pytanie, nie dbają o to, czy zostanie użyte polecenie uśpienia :)
donquixote
8

Możesz to zrobić za pomocą oprogramowania innych firm.

Opcja, która działała dla mnie dobrze, to częsty cron

Umożliwia precyzję w milisekundach i daje możliwość odroczenia następnego wykonania, dopóki bieżąca nie zostanie zakończona.

thatjuan
źródło
1
Frequent-cron również działał dobrze dla nas i zasila wiele naszych systemów produkcyjnych. Nigdy nie mieliśmy z tym problemu.
Homer6
2

Miałem kilka problemów:

(1) czasami system jest zajęty i nie może uruchomić rzeczy dokładnie w 30 sekundowym punkcie, wówczas możliwe jest, że w tym samym czasie, gdy wykonujesz jedno zadanie, inne zadanie wyskakuje, a następnie masz 2 (lub więcej) zadań wykonujących to samo rzecz. W zależności od skryptu mogą występować tutaj znaczne zakłócenia. Zatem kodowanie w takim skrypcie powinno zawierać pewien kod, aby zapewnić, że jednocześnie działa tylko jedna instancja danego skryptu.

(2) Skrypt może mieć dużo narzutu i zużywać więcej zasobów systemowych, niż chcesz. Dzieje się tak, jeśli konkurujesz z wieloma innymi działaniami systemowymi.

Tak więc, jak to ujął jeden plakat, w tym przypadku poważnie zastanowiłbym się nad uruchomieniem demona z dodatkowymi procesami, aby upewnić się, że pozostanie uruchomiony, jeśli ma to kluczowe znaczenie dla twoich operacji.

mdpc
źródło
1

moje najprostsze i ulubione rozwiązanie do tego zadania:

wpis cron:
* * * * * flock -w0 /path/to/script /path/to/script

scenariusz:
while true;do echo doing something; sleep 10s;done

leniwa alternatywa: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

lub

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

profesjonaliści

  • użycie flockpolecenia pozwala uniknąć uruchamiania skryptu przez wiele instancji w tym samym czasie. W większości przypadków może to być bardzo ważne.
  • flocki watchpolecenia są dostępne w większości instalacji Linuksa

Cons

  • zatrzymanie tego rodzaju „usługi” wymaga dwóch kroków
    • skomentuj wpis crona
    • zabij skrypt lub watchpolecenie
asvany
źródło
2
Czy ktoś może to wytłumaczyć nowicjuszowi z Linuksem - za i przeciw? Dzięki ..
a20
@asvany Myślę, że podoba mi się to rozwiązanie, ale jako a20, czy mógłbyś zamieścić jakieś wyjaśnienie dla „zielonego” linuksa, proszę? ty.
JoelAZ
0

Rozwiązanie, jeśli dotyczy twojego własnego skryptu lub możesz go owinąć:

  1. Uzyskaj i zapamiętaj czas rozpoczęcia.
  2. Jeśli plik blokady, którego będziesz dotykać później, jest obecny, a skrypt nie działa przez 60 sekund, poczekaj sekundę i sprawdź ponownie. (np. podczas / sen) *
  3. Jeśli plik blokady jest nadal obecny po upływie 60 sekund, wyjdź z ostrzeżeniem o nieaktualnej blokadzie.
  4. Dotknij pliku blokady.
  5. Chociaż skrypt nie był uruchomiony przez 60 sekund, zapętl swoje aktualne zadanie z pożądanym czasem trwania snu.
  6. Usuń plik blokady.
  7. Dodaj jak najdrobniejsze cron.
  8. Bob jest Twoim wujkiem.

Mniej bólu głowy niż budowanie i monitorowanie demona.

* Jeśli używasz PHP, pamiętaj o clearstatcache ().

Ktoś
źródło