Mam serwer, który normalnie jest wyłączony ze względów bezpieczeństwa. Kiedy chcę nad tym popracować, włączam go, wykonuję zadania i zamykam ponownie. Moje zadania zwykle nie trwają dłużej niż 15 minut. Chciałbym wdrożyć mechanizm automatycznego wyłączania po 60 minutach.
Zbadałem, jak to zrobić z cronem, ale nie sądzę, że jest to właściwy sposób, ponieważ cron nie bierze pod uwagę, kiedy serwer był ostatnio włączony. Mogę ustawić tylko okresowe wzorce, ale nie uwzględniają tych danych.
Jak mogę to zrobić?
at
(wykonanie jednorazowe).sudo shutdown -h +60
odliczanie, które uruchomi 60-minutowy licznik dla procesu zamykania (-halt). Jeśli chcesz to anulować, możeszsudo shutdown -c
(to nie używa crona)Odpowiedzi:
Jeśli wykonujesz zadania jako ten sam użytkownik za każdym razem, możesz po prostu dodać polecenie zamykania, opcjonalnie z opcją -P, do swojego profilu. Liczba oznacza liczbę minut, po których polecenie zamknięcia jest opóźnione. Upewnij się, że użytkownik ma możliwość wykonania polecenia zamknięcia za pośrednictwem sudo bez hasła.
źródło
shutdown -k -P 3600
vsshutdown -k -P 60
(-k
drukuje wiadomość na ścianie, ale nie ma innego efektu)Istnieje kilka opcji.
Zapewnij czas bezpośrednio na
shutdown -P
:Zauważ, że
shutdown
strona podręcznika wskazuje również:Użyj
at
polecenia.Utwórz plik jednostki systemowej lub skrypt inicjujący, który będzie uruchamiany
shutdown -P 60
podczas uruchamiania.Użyj crona,
@reboot
aby uruchomić polecenie po uruchomieniu.Dodaj do (root) crontab:
W przypadku dwóch ostatnich metod można również użyć
sleep 3600 && shutdown -P now
zamiast argumentu czasu,shutdown
aby opóźnić zamknięcie systemu o 60 minut. W ten sposób logowanie jest możliwe do ostatniej chwili przed zamknięciem systemu.źródło
sleep
polecenia nadal musisz określić czasshutdown
- chcielibyśmy użyćnow
tego argumentu, jeśli już zrobiliśmy czekanie (ale pamiętaj, że nie dostaniesz zbyt wiele ostrzeżenia, aby zapisać swoją pracę przed nim znika spod ciebie!).shutdown -P 60
działa, nie jest to sposób, w jaki należy wywoływać polecenie. Według strony podręcznika, której powinieneś użyćshutdown -P +60
. --- Również zamknięcie bez argumentu czasowego (w tym przykładziesleep 3600 && shutdown -P
) zostanie opóźnione o jedną minutę (jakshutdown -P +1
). Jak napisał Toby Speight, prawdopodobnie będziesz chciał użyćshutdown -P now
.To wygląda na problem XY .
Jeśli zamkniesz się po 60 minutach, ryzykujesz, że masz szczególnie skomplikowany problem i potrzebujesz więcej czasu. Wiele wcześniejszych rozwiązań nie ułatwiłoby opóźnienia wyłączenia.
Jeśli zadanie nie jest zadaniem interaktywnym, ale jest zadaniem skryptowym, które jest automatycznie uruchamiane z innej maszyny, @sdkks daje świetne rozwiązanie tego problemu ; naprawdę powinieneś po prostu zlecić maszynie wyłączenie zasilania, gdy tylko skrypt i wszystkie jego zadania zakończą się.
Jeśli jednak twoje zadanie jest zadaniem interaktywnym, sugeruję zamiast tego wykonać wykrywanie bezczynności.
Jeśli wykonujesz swoje zadanie w GUI (X11), możesz wykryć bezczynne sesje GUI, korzystając z opisanego tutaj podejścia: Uruchom polecenie, gdy system jest w stanie bezczynności i gdy jest ponownie aktywny
Jeśli wykonasz zadanie za pośrednictwem terminala, możesz wykryć zalogowanych użytkowników za pomocą
who
polecenia. Możesz skonfigurować cronjob, który wyłącza maszynę, jeśliwho
zwróci pusty wynik. Zauważ, że będzie to dość konserwatywne podejście; nie zamknie systemu, jeśli konsola pozostanie podłączona, ale pozostanie bezczynna.Jeśli chcesz być nieco bardziej agresywny i rozłączać bezczynne sesje terminali, możesz połączyć poprzednie podejście z automatycznym rozłączaniem bezczynnych sesji SSH
ClientAliveInterval
iClientAliveCountMax
. Innym podejściem w tym przypadku, jeśli nie masz SSH, ale masz lokalną sesję terminala, jest użycie czasu bezczynności terminala zwróconego przezw
polecenie.źródło
Chociaż wszystkie poprzednie odpowiedzi tutaj spełniają wymóg doskonałości, możesz również wyłączyć maszynę, gdy tylko zadania zostaną wykonane.
bash
skrypty mogą byćtrap
ped, co oznacza, że niektóre sygnały mogą być przechwytywane, a niektóre zadania mogą być wykonywane w razie potrzeby.EXIT
jest jednym z sygnałów, które mogą zostać uwięzione.Byłbyś w stanie:
trap
dlaEXIT
swoich automatycznych skryptów powłoki, co oznacza zakończenie automatycznych zadańtrap
dla swojego.bashrc
EXIT
, co oznacza, że za każdym razem, gdy wylogujesz się z tego urządzenia, wyłącz je.Opcja nr 1 byłaby idealnym rozwiązaniem, pod warunkiem, że twoje zadania nie wymagają kontroli adhoc i ręcznej oceny.
Opcja nr 2 obejmowałaby przypadki, w których zapomniałbyś wyjść z terminala bez wyłączania zasilania. Jest jednak zastrzeżenie; jeśli masz wiele otwartych terminali na tym samym komputerze i wyjdziesz z jednego z nich, nadal będzie ono wyłączać urządzenie. (Można tego użyć w skryptach, aby tego uniknąć, ale nie skomplikuję rozwiązania).
Może to być na końcu
.bashrc
opcji nr 2, gdzieś na górze skryptu dla opcji nr 1.Dlaczego nie użyć
poweroff
na końcu skryptu?Wolę używać
set -eo pipefail
na górze moich skryptów. Jeśli wystąpi jakikolwiek błąd, nie po cichu zawiedzie; przestanie wykonywać więcej poleceń.trap
zEXIT
sygnałem powinno obejmować przypadki, gdy skrypt kończy się przedwcześnie z powodu błędów.Jednak w przypadku zadań może to również oznaczać, że urządzenie zostanie zamknięte przed ich zakończeniem.
Mam prosty
bash
szablon, którego używam, aby ułatwić debugowanie skryptów; może to może się przydać. Zobacz tę treść .źródło
.bashrc
wolałbym dół, na wypadek gdyby coś innego go nadpisało . Twoje obawy nie wydają się jasne, czy możesz udostępnić przykładowy fragment na repl.it?Opracowanie na @dirkt komentarza można wstawić
at
polecenia na swój.bashrc
lub.profile
lub inny plik twoi zastosowania powłoki przy logowaniu, aby zaplanować automatyczne wyłączenie po 60 minutach loginu.Coś jak:
źródło
at
samego początku. Możesz również zobaczyćat
zadania w/var/spool/
at
w tym kontekście, ponieważ przetrwa ponowne uruchomienie. Jeśli OP miałby się zalogować, ręcznie zamknąć, a następnie zalogować się ponownie w ciągu godziny, zostałby wyrzucony przed upływem godziny po ostatnim logowaniu, kiedy nastąpi pierwsze zaplanowane zamknięcie.Następujące działa
command
z parametrami, a jeśli zakończy się pomyślnie, natychmiast wyłączy to pole, zakładając, że użytkownik może uruchomićpoweroff
. Może być konieczne użyciesudo poweroff
.Podczas gdy następujący po prostu uruchamia się
poweroff
natychmiast po zakończeniu polecenia:Jeśli uważasz, że polecenie wymaga odpoczynku po zakończeniu, uruchom
Jeśli uważasz, że polecenie może być uruchamiane w godzinach nadliczbowych, możesz ograniczyć je do godziny:
timeout
jest częściącoreutils
pakietu, więc prawdopodobnie już go masz.źródło
Jeśli naprawdę martwisz się bezpieczeństwem, użyj mechanicznego wyłącznika czasowego na źródle zasilania. Po prostu ustaw na czas, w którym chcesz się zamknąć. W ten sposób nikt nie może zalogować się zdalnie i wyłączyć wyłączenia. Potrzebujesz fizycznego dostępu.
źródło
Jeśli jesteś w
systemd
maszynie, możesz użyć monotonicznego timeraJednostka czasowa
/etc/systemd/system/shutdown_after_an_hour.timer
Jednostka czasowa
/etc/systemd/system/shutdown_after_an_hour.service
:Jest włączony przez
Jego status (szczególnie ile czasu pozostało do wyłączenia) jest dostępny za pośrednictwem
Będzie działał przy następnym ponownym uruchomieniu, nie będzie dla
systemctl start
niego przydatny podczas sesji, gdy zostanie utworzony, ponieważ albo nie będzie działał (ponieważ nie został uruchomiony podczas ponownego uruchamiania), albo od razu zamknie maszynę, jeśli minęła godzina. Nie wiem, co się wydarzy, nigdy nie testowałem tego konkretnego przypadku.źródło
Spróbuj umieścić skrypt (
sudo shutdown -P 3600
) w/etc/init.d
katalogu, aby uruchomić go automatycznie podczas uruchamiania.Lub spróbuj użyć
anacron
, dodając polecenie do/etc/anacrontab
pliku. Sugeruję również użycienohup
przed poleceniem, aby upewnić się, że polecenie nadal działa po wylogowaniu.źródło
Wykorzystaj plik wylogowania swojej powłoki
Jeśli potrzebujesz tylko serwera do interaktywnych lub nieinteraktywnych zadań uruchomionych przez UID, rozważ umieszczenie poleceń zamykania w pliku ~ / .bash_logout . Podręcznik GNU Bash mówi:
Tak więc dodanie „sudo poweroff” lub podobnego do pliku wylogowania spowoduje wyłączenie serwera, gdy tylko wylogujesz się z bieżącej sesji lub gdy zadzwoni nieinteraktywna sesja Bash
exit
. Można również zdecydować się na stosowanie u lub przekazać opóźnienia czasowego do wyłączenia , jeśli wolisz, aby odroczyć zamknięcie.Aby uzyskać bardziej interaktywne podejście do tego, możesz umieścić następujące Bashisms w pliku wylogowania:
Ostrzeżenia
Jest kilka ostrzeżeń, o których należy pamiętać w związku z tym rozwiązaniem:
startx
lub podobną.exit
, mogą wystąpić wyłączenia, których się nie spodziewasz.NOPASSWD
komend zamykania systemu lub jeśli nie zadzwoniłeśsudo -v
przed uruchomieniem komendy zamykania systemu.Krótko mówiąc, możesz zastanowić się, czy to podejście spełnia twoje rzeczywiste potrzeby, czy też zupełnie inne podejście, takie jak monitorowanie braku zalogowanych użytkowników lub inna alternatywa, jest lepszym rozwiązaniem. Twój przebieg na pewno będzie się różnić.
źródło