Jak zatrzymać skrypt w określonym czasie, dopóki cron nie uruchomi go ponownie?

12

Mam Raspberry Pi z systemem OSMC (oparty na Debianie).

Ustawiłem zadanie crona, aby uruchomić skrypt, sync.sh, o północy.

0 0 * * * /usr/local/bin sync.sh

Muszę zatrzymać skrypt o 7 rano. Obecnie używam:

0 7 * * * shutdown -r now

Czy jest lepszy sposób? Mam wrażenie, że ponowne uruchomienie to przesada.

Dzięki

Anthony
źródło

Odpowiedzi:

25

Możesz uruchomić go za pomocą timeoutpolecenia ,

timeout - run a command with a time limit

Synopsis
timeout [OPTION] NUMBER[SUFFIX] COMMAND [ARG]...
timeout [OPTION]
Description

Start COMMAND, and kill it if still running after NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. 

PS. Jeśli proces synchronizacji trwa zbyt długo, możesz rozważyć inne podejście do synchronizacji danych, np. Zablokować replikację.

Rabin
źródło
Moje połączenie internetowe jest wolne, dlatego synchronizacja trwa tak długo. Czy poleciłbyś jakiś konkretny sygnał?
Anthony
@Anthony, jak teraz synchronizujesz?
Rabin
lftp.tech
Anthony
@Anthony możesz wypróbować inną aplikację, taką jak syncthing ( syncthing.net ) lub BTSync ( resilio.com ), które działają na poziomie bloku pliku do synchronizacji
Rabin
9

Jeśli synchronizacja może być kontynuowana po 17 godzinach hibernacji, spróbuj

0 0 * * * killall -CONT -g sync.sh || /usr/local/bin/sync.sh
7 0 * * * killall -STOP -g sync.sh

Jeśli synchronizacja woli zacząć od nowa, spróbuj

0 0 * * * exec /usr/local/bin/sync.sh
7 0 * * * killall -TERM -g sync.sh

Jeśli synchronizacja lub podzadania ignorują sygnały, ale nie pozostawiają resztek, zrób to

0 0 * * * exec /usr/local/bin/sync.sh
7 0 * * * killall -KILL -g sync.sh

killallpsmisc

Roman Czyborra
źródło
Korzystam ze skryptu znajdującego się poniżej, z kopią lustrzaną -c nie wydaje się, żeby ponowne uruchomienie nastąpiło. Które z powyższych poleciłbyś ?: gist.github.com/feralhosting/4e7e93a7fecd8f55cb4a
Anthony
Widząc ten skrypt LFTP, który chce, aby SIGTERM wyczyścił swój plik blokujący, i biorąc pod uwagę prawdopodobieństwo przekroczenia limitu czasu serwera przez 17 godzin bezczynności lub nawet gorszej numeracji inet [64], wybrałbym wariant 0 0 * * * timeout 7h /usr/local/bin/sync.shmój lub w większości taki sam killall -TERM.
Roman Czyborra
4

Używałbym również crona do „zatrzymania” lub „zabicia” tej usługi lub skryptu w określonym czasie.
Najpierw utwórz zadanie cron, aby uruchomić zadanie lub skrypt. (możesz łatwo uruchomić innego crona, który zabije zadanie o nazwie sudo pkill wget)

Po drugie, chcesz zobaczyć uruchamianie zadań crontab, w użytecznym i czytelnym formacie, w wynikach:

   ps -o pid,sess,cmd afx | egrep "( |/)cron( -f)?$"

Pojawią się w pierwszych wierszach, mniej więcej tak:

1108  1108 cron
4288  1108 \_ CRON
4289  4289     \_ /bin/sh -c /path/to/my/crontab/script1.sh
4290  4289         \_ /bin/bash /path/to/my/crontab/script1.sh
4295  4289             \_ /usr/bin/wget LINK

Pierwsza kolumna to PID, druga to identyfikator sesji, a trzecia to polecenie uruchomione przez crona. Możesz zabić wszystkie procesy związane z konkretnym zadaniem cron przy użyciu identyfikatora sesji, więc w powyższym przykładzie powinieneś zabić identyfikator sesji 4289:

   pkill -s 4289

Musisz umieścić pkill w skrypcie i uruchomić go jako cron

ddlingo
źródło
Czy identyfikator sesji zmieni się przy każdym uruchomieniu zadania CRON? A co po wyłączeniu i włączeniu?
Anthony
tak to się zmieni. Ale jeśli go napiszesz, możesz uzyskać PID i umieścić go w zmiennej. Możesz być w stanie po prostu użyć nazwy, jeśli się pojawi. pkill sync.sh
ddlingo