Jak używać polecenia limitu czasu w systemie Linux

W dzisiejszych czasach warto ograniczyć czas spędzany na komputerze. Możesz nadać procesom ograniczenia czasowe, ustawiając maksymalny czas, przez jaki mogą działać, za pomocą polecenia timeout. Oto samouczek dotyczący ograniczania uruchamiania programów przy użyciu tego polecenia.

Co robi dla Ciebie limit czasu?

Polecenie limitu czasu umożliwia ustawienie limitu czasu dla działania programu. Ale dlaczego warto to robić?

Jednym z przypadków zastosowania jest sytuacja, w której wiesz dokładnie, jak długo ma działać proces. Typowym przypadkiem użycia jest kontrolowanie limitu czasu programu rejestrującego lub przechwytującego dane, aby pliki dziennika nie zajmowały nieustannie miejsca na dysku twardym.

Innym przypadkiem jest sytuacja, gdy nie wiesz, jak długo chcesz, aby proces działał, ale wiesz, że nie chcesz, aby działał w nieskończoność. Możliwe, że masz zwyczaj minimalizowania okna terminala i zapominania o uruchomionych procesach.

Niektóre programy – nawet proste narzędzia – mogą generować ruch w sieci na poziomach, które mogą utrudniać działanie sieci lub związać zasoby na urządzeniu docelowym, spowalniając jego wydajność. Pozostawienie takich programów uruchomionych przez dłuższy czas, gdy jesteś z dala od komputera, jest złą praktyką.

Polecenie timeout jest częścią Narzędzi GNU Core, więc systemy operacyjne Linux i Unix, takie jak macOS, mają wbudowane to narzędzie. Nie ma nic do zainstalowania; możesz je używać zaraz po wyjęciu z pudełka.

Pierwsze kroki z przekroczeniem limitu czasu

Oto prosty przykład. Z domyślnymi opcjami wiersza poleceń polecenie ping będzie działać, dopóki go nie zatrzymasz, naciskając Ctrl + C. Jeśli tego nie przerwiesz, będzie działać w nieskończoność.

ping 192.168.4.28

Używając limitu czasu, możemy upewnić się, że ping nie będzie działać w nieskończoność, pogarszając przepustowość sieci i obciążając każde urządzenie, do którego jest wysyłane polecenie ping.

To następne polecenie używa limitu czasu do ograniczenia czasu działania ping. Dajemy 15 sekund na wykonanie polecenia ping.

timeout 15 ping 192.168.4.28

Po 15 sekundach limit czasu kończy sesję ping i wracamy do wiersza poleceń.

Używanie limitu czasu z innymi jednostkami czasu

Zauważ, że nie musieliśmy dodawać „s” za 15. limitem czasu, przy założeniu, że wartość jest w sekundach. Możesz dodać „s”, ale to naprawdę nie ma znaczenia.

Aby użyć wartości czasu mierzonej w minutach, godzinach lub dniach, dodaj „m”, „h” lub „d”.

Aby ping działał przez trzy minuty, użyj następującego polecenia:

timeout 3m ping 192.168.4.28

Ping będzie działał przez trzy minuty, po czym upłynie limit czasu i zatrzyma sesję ping.

Ograniczanie przechwytywania danych z przekroczeniem limitu czasu

Niektóre pliki przechwytywania danych mogą bardzo szybko urosnąć. Aby zapobiec nieporęczności lub problematycznym rozmiarom takich plików, ogranicz czas, przez jaki może działać program przechwytujący.

W tym przykładzie używamy tcpdump, narzędzia do przechwytywania ruchu sieciowego. Na maszynach testowych, na których badano ten artykuł, tcpdump był już zainstalowany w systemach Ubuntu Linux i Fedora Linux. Musiał być zainstalowany na Manjaro Linux i Arch Linux za pomocą następującego polecenia:

sudo pacman -Syu tcpdump

Możemy uruchomić tcpdump przez 10 sekund z jego domyślnymi opcjami i przekierować jego dane wyjściowe do pliku o nazwie capture.txt za pomocą następującego polecenia:

timeout 10 sudo tcpdump > capture.txt

(Tcpdump ma własne opcje zapisywania przechwyconego ruchu sieciowego do pliku. To szybki hack, ponieważ omawiamy limit czasu, a nie tcpdump.)

Tcpdump zaczyna przechwytywać ruch sieciowy i czekamy 10 sekund. I pojawia się i znika 10 sekund, a tcpdump nadal działa, a rozmiar pliku capture.txt wciąż rośnie. Aby zatrzymać tcpdump, potrzeba pospiesznego Ctrl + C.

Sprawdzenie rozmiaru pliku capture.txt za pomocą ls pokazuje, że w ciągu kilku sekund urósł on do 209K. Ten plik szybko się rozrastał!

ls -lh capture.txt

Co się stało? Dlaczego limit czasu nie zatrzymał tcpdump?

Wszystko ma związek z sygnałami.

Wysyłanie właściwego sygnału

Gdy limit czasu chce zatrzymać program, wysyła sygnał SIGTERM. To grzecznie prosi program o zakończenie. Niektóre programy mogą ignorować sygnał SIGTERM. Kiedy tak się stanie, musimy ustawić limit czasu, aby był nieco bardziej zdecydowany.

Możemy to zrobić, prosząc o podanie limitu czasu, aby zamiast tego wysłać sygnał SIGKILL.

Sygnał SIGKILL nie może być „złapany, zablokowany ani zignorowany” – zawsze dociera. SIGKILL nie prosi grzecznie o zatrzymanie programu, raczej działa zdecydowanie.

Możemy użyć opcji -s (signal), aby określić limit czasu na wysłanie sygnału SIGKILL.

timeout -s SIGKILL 10 sudo tcpdump > capture.txt

Tym razem po upływie 10 sekund tcpdump zostaje zatrzymany.

Najpierw uprzejmie prosić

Możemy poprosić o limit czasu, aby spróbować zatrzymać program za pomocą SIGTERM i wysłać SIGKILL tylko wtedy, gdy SIGTERM nie działa.

Aby to zrobić, używamy opcji -k (kill after). Opcja -k wymaga wartości czasu jako parametru.

W tym poleceniu prosimy o przekroczenie limitu czasu, aby dmesg działał przez 30 sekund, a następnie go zakończył sygnałem SIGTERM. Jeśli dmesg nadal działa po 40 sekundach, oznacza to, że dyplomatyczny SIGTERM został zignorowany, a limit czasu powinien wysłać SIGKILL, aby zakończyć zadanie.

dmesg to narzędzie, które potrafi monitorować komunikaty bufora pierścieniowego jądra i wyświetlić je w oknie terminala.

timeout -k 40 30 dmesg -w

dmesg działa przez 30 sekund i zatrzymuje się, gdy odbierze sygnał SIGTERM.

Wiemy, że to nie SIGKILL zatrzymał dmesg, ponieważ SIGKILL zawsze pozostawia jednowyrazowy nekrolog w oknie terminala: „Zabity”. W tym przypadku tak się nie stało.

Pobieranie kodu zakończenia programu

Po zakończeniu działania programy przekazują wartość z powrotem do powłoki. Nazywa się to kodem zakończenia. Zwykle służy to do poinformowania powłoki – lub jakiegokolwiek innego procesu, który uruchomił program – czy wystąpiły problemy podczas działania programu.

Polecenie timeout zapewnia własny kod zakończenia, ale może nas to nie obchodzić. Prawdopodobnie bardziej interesuje nas kod wyjścia z procesu, który kontroluje przekroczenie czasu.

To polecenie pozwala pingowi działać przez pięć sekund. Pinguje komputer o nazwie Nostromo, który znajduje się w sieci testowej, użytej do zbadania tego artykułu.

timeout 5 ping Nostromo.local

Polecenie działa przez pięć sekund i kończy się przez limit czasu. Następnie możemy sprawdzić kod zakończenia za pomocą tego polecenia:

echo $?

Kod zakończenia to 124. Jest to wartość używana przez limit czasu do wskazania, że program został zakończony za pomocą SIGTERM. Jeśli SIGKILL kończy program, kod zakończenia to 137.

Jeśli przerwiemy program za pomocą Ctrl + C, kod wyjścia z limitu czasu wynosi zero.

timeout 5 ping Nostromo.local
echo $?

Jeśli wykonanie programu zakończy się przed upływem limitu czasu, timeout może przekazać kod zakończenia z programu z powrotem do powłoki.

Aby tak się stało, program musi samoczynnie zatrzymać się (innymi słowy, nie być zakończony przez przekroczenie limitu czasu) i musimy użyć opcji –preserve-status.

Jeśli użyjemy opcji -c (count) z wartością pięć, ping spowoduje uruchomienie tylko pięciu żądań. Jeśli podamy limit czasu wynoszący jedną minutę, ping z pewnością sam się zakończy. Następnie możemy sprawdzić wartość wyjścia za pomocą echo.

timeout --preserve-status 1m ping -c 5 Nostromo.local
echo $?

Ping kończy pięć żądań ping i kończy. Kod zakończenia to zero.

Aby sprawdzić, czy kod zakończenia pochodzi z polecenia ping, wymuśmy ping, aby wygenerował inny kod zakończenia. Jeśli spróbujemy wysłać żądania ping na nieistniejący adres IP, polecenie ping zakończy się niepowodzeniem i zostanie wyświetlony kod zakończenia błędu. Następnie możemy użyć echo, aby sprawdzić, czy kod zakończenia jest różny od zera.

timeout --preserve-status 1m ping -c 5 NotHere.local
echo $?

Polecenie ping oczywiście nie może dotrzeć do nieistniejącego urządzenia, więc zgłasza błąd i zamyka się. Kod wyjścia to dwa. To kod zakończenia używany przez polecenie ping w przypadku błędów ogólnych.

Ustalanie podstawowych zasad

Timeout polega na wyznaczeniu pewnych granic dla uruchomionych programów. Jeśli istnieje niebezpieczeństwo, że pliki dziennika mogą przepełnić dysk twardy lub jeśli zapomnisz, że zostawiłeś uruchomione narzędzie sieciowe, zawiń je w czasie i pozwól komputerowi na samoregulację.