Jak zabić skrypt działający w terminalu bez zamykania terminalu (Ctrl + C nie działa)?

36

Napisałem skrypt bash, który wywołuje kilka innych programów i wykonuje wiele poleceń. Uruchamiam ten skrypt z terminala. Teraz chcę zabić skrypt.

Wydaje Ctrl + Cmi się, że naciśnięcie czasami tego nie wycina, ponieważ czasami skrypt wykonuje inny program iz jakiegoś powodu sygnał zabicia nie działa.

Jeśli jednak zamknę okno terminalu, skrypt zostanie zabity.

Czy jest coś, co mogę zrobić (kombinacja klawiatury), analogicznie do zamykania okna terminala, bez faktycznego zamykania okna terminala (nie chcę stracić historii poleceń, bieżącego katalogu, historii danych wyjściowych itp.)?

becko
źródło
8
W takich przypadkach próbujęCtrl + z
kenn
A po Ctrl + zbiegu:kill -9 $(pgrep -f your_script.sh)
Noam Manos

Odpowiedzi:

38

Masz kilka opcji. Jednym z nich jest zatrzymanie skryptu ( CtrlZ), uzyskanie PID skryptu i wysłanie SIGKILLdo grupy procesów.

Gdy polecenie jest wykonywane w powłoce, rozpoczyna się proces, a wszystkie jego elementy potomne są częścią tej samej grupy procesów (w tym przypadku grupy procesów pierwszego planu). Aby wysłać sygnał do wszystkich procesów w tej grupie, należy wysłać go do lidera procesu. W killpoleceniu lider procesu jest oznaczony w następujący sposób:

kill -PID

Gdzie PIDjest identyfikator procesu skryptu.

Przykład:

Rozważ skrypt, test.shktóry uruchamia niektóre procesy. Powiedzmy, że uruchomiłeś go w powłoce:

$ ./test.sh

W innym terminalu

$ pgrep test.sh
17802
$ pstree -ps `!!`
pstree -ps `pgrep test.sh`
init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)
                                                                               ├─sleep(17805)
                                                                               └─yes(17803)

W takim przypadku, aby wysłać sygnał do grupy procesów utworzonej przez test.sh, wykonaj następujące czynności:

kill -INT -17802

-INTsłuży do wysyłania SIGINT, więc to polecenie jest równoważne naciśnięciu CtrlCna terminalu. Aby wysłać SIGKILL:

kill -KILL -17802

Musisz tylko zatrzymać skrypt, jeśli nie możesz otworzyć innego terminalu. Jeśli możesz, użyj, pgrepaby znaleźć PID.

Jednym z poleceń uruchamianych przez skrypt może być zalewkowanie SIGINT, co prawdopodobnie CtrlCjest nieskuteczne. Nie SIGKILLmożna go jednak uwięzić i zwykle jest to opcja ostateczna . Możesz spróbować SIGTERM( -TERM) przed zabiciem. Ani SIGKILLczy SIGTERMmożna ustawić jako skrót klawiaturowy droga SIGINTjest.

Wszystko to jest dyskusyjne, jeśli twój skrypt nie zawiera linii shebang. Z tej SO odpowiedzi :

Zwykle powłoka nadrzędna zgaduje, że skrypt jest napisany dla tej samej powłoki (minimalne powłoki podobne do Bourne'a uruchamiają skrypt za pomocą / bin / sh, bash uruchamia go jako podproces bash) ...

Z tego powodu, gdy skrypt jest wykonywany, nie znajdziesz procesu o nazwie skryptu (lub procesu z nazwą skryptu w wierszu poleceń) i pgrepzakończy się niepowodzeniem.

Zawsze używaj linii shebang.

muru
źródło
Czy istnieje kombinacja klawiszy dla SIGKILLlub SIGTERM?
becko
@becko Nie, a nie możesz go skonfigurować: superuser.com/a/417991/334516
muru
pgrep test.shnie zwraca mi PID. Próbowałem prostego testu.sh: for i in {1..30}; do sleep 1 echo $i done Podczas test.shdziałania wykonuję pgrep test.shw innym terminalu, ale nic nie jest zwracane. Co jest nie tak?
becko
1
@becko, jak uruchomiłeś skrypt? Spróbuj także pgrep -f test.sh.
muru
pgrep -f test.shteż nie działa. ./test.sh
Uruchamiam
6

Jeśli znasz procesy związane ze skryptem, możesz znaleźć ich PID za pomocą

 ps -A

a następnie użyj numeru PID, aby zabić odpowiednie procesy za pomocą

 kill -9 PID_Number
Harris
źródło
1
To zbyt skomplikowane. Skrypt spawnuje kilka innych programów, a te programy również spawnują równoległe procesy. Bardzo trudno jest śledzić wszystkie te procesy. Musi istnieć prostsze rozwiązanie, coś analogicznego do tego, co dzieje się po zamknięciu okna terminala.
becko
Czy możesz spróbować pkill -P $$
Harris
1

Jak powiedział Harris, możesz uruchomić, Kill -9 PID_Numberale możesz także zainstalować pakiet znany jako htopposiadający interaktywną przeglądarkę procesów, która znacznie ułatwia znajdowanie określonych procesów. htop obsługuje również procesy zabijania.

Bulbasaur pozbawiony snu
źródło