Czysty bash
wbudowany, bez rdzeni
Odkryłem, że to rozwiązanie działa w bash
oparciu o wbudowane polecenie bez wywoływania zewnętrznego pliku wykonywalnego. Działa na systemie, na którym ostatecznie nie są nawet zainstalowane coreutils [ 1 ]
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
Objaśnienia : jak zwykle po wysłaniu komendy w tle z &
jego PID jest przechowywany w zmiennej wewnętrznej $!
(obecne w nowoczesnej wersji dash
, csh
, bash
, tcsh
, zsh
...).
To, co naprawdę robi różnicę między powłokami, to obecność wbudowanego polecenia read
[ 2 ] i opcji -t
. W pierwszej wersji, jeśli użytkownik nie wypełni wiersza wprowadzania przed określoną liczbą sekund, instrukcja zostanie zakończona i wygenerowany zostanie kod powrotu błędu.
-t TIMEOUT Powoduje przekroczenie limitu czasu odczytu i zwrócenie błędu, jeśli pełny wiersz danych wejściowych nie zostanie odczytany w ciągu TIMEOUT sekund.
Druga wersja działa jako pierwsza, ale możesz anulować limit czasu zabijania po prostu naciskając enter.
Rzeczywiście operator lub ||
wykonuje kill
instrukcję tylko wtedy, gdy read
polecenie zakończy działanie z kodem powrotu innym niż zero, tak jak po upływie limitu czasu. Jeśli naciśniesz enterprzed tym momentem, zwróci 0 i nie zabije twojego poprzedniego polecenia.
Rozwiązania Coreutils [ 1 ]
Gdy w twoim systemie znajdują się coreutils i nie musisz oszczędzać czasu i zasobów, aby wywołać program zewnętrzny, timeout
i sleep
oba są idealnymi sposobami na osiągnięcie celu.
timeout
Korzystanie z timeout
jest proste.
W końcu możesz rozważyć skorzystanie z -k
opcji wysłania dodatkowego sygnału zabicia, jeśli pierwszy się nie powiedzie.
timeout 5m YourCommand # 3rd version
sleep
Dzięki sleep
niemu możesz wykorzystać swoją fantazję lub czerpać inspiracje [ 3 ] . Pamiętaj, że możesz pozostawić swoje polecenie w tle lub na pierwszym planie (np. top
Zwykle musi znajdować się na pierwszym planie).
YourCommand & sleep 5m; kill $! # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) & # 5th Background
bash -c '(sleep 5m; kill $$) & exec YourCommand' # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground
Objaśnienia
- W czwartej wersji wykonujesz w tle,
YourCommand
a następnie twoja skorupa sleep
przez 5 minut. Kiedy zostanie zakończony, ostatni proces w tle ( $!
) zostanie zabity. Zatrzymaj swoją skorupę.
-
W wersji 5 wykonujesz natomiast w tle
YourCommand
i od razu zapisujesz ten PID w zmiennej $pid
. Następnie wykonujesz drzemkę w tle przez 5 minut i wynikające z niej polecenie, które zabije zapisany PID. Ponieważ wysłałeś tę grupę poleceń w tle, nie zatrzymujesz powłoki. Musisz zapisać PID w zmiennej, ponieważ wartość $!
może zostać zaktualizowana przez ewentualne wykonanie innego programu w tle. Krótko mówiąc, unikasz ryzyka zabicia niewłaściwego procesu lub jego braku.
- W szóstej wersji nazywa się to nową powłoką bash, która samobójczo za 5 minut
$$
, następnie wykonuje polecenie, które pozostaje na pierwszym planie.
- W siódmej wersji wywoływana jest podpowłoka,
()
która przechowuje swój PID w zmiennej ( cmdpid
) i zabija się za pomocą innej podpowłoki wysyłanej w tle, a następnie uruchamia YourCommand na pierwszym planie.
Oczywiście w każdej wersji możesz wysłać potrzebny ci sygnał zabójstwa, od domyślnego do skrajnego kill -9
, do użycia tylko wtedy, gdy jest naprawdę potrzebny.
Bibliografia
- [ 1 ] Coreutils
- [ 2 ] Przewodnik dla początkujących Bash
- [ 3 ] BashFAQ