Co zrobić, gdy Ctrl + C nie może zabić procesu?

171

Ctrl+ Cnie zawsze działa w celu zabicia bieżącego procesu (na przykład, jeśli proces ten jest zajęty w niektórych operacjach sieciowych). W takim przypadku po prostu widzisz „^ C” za kursorem i nie możesz zrobić wiele więcej.

Jak najłatwiej zmusić ten proces do śmierci teraz bez utraty terminala?

Podsumowanie odpowiedzi: Zazwyczaj możesz Ctrl+ Zuśpić proces, a następnie zrobić kill -9 _process-pid_, gdy znajdziesz pid procesu za pomocą ps i innych narzędzi. W Bash (i ewentualnie innych powłokach) możesz zrobić kill -9 %1(lub ogólnie „% N”), co jest łatwiejsze. Jeśli Ctrl+ Znie działa, będziesz musiał otworzyć inny terminal i zabić stamtąd.

Dustin Boswell
źródło
screenbyłoby możliwym rozwiązaniem, umożliwiającym utworzenie nowego okna i killstamtąd proces.
Bobby,
2
zakładając, że byłeś już na ekranie :)
Dustin Boswell

Odpowiedzi:

119

Aby zrozumieć problem, dlaczego Ctrl+ Cnie działa, bardzo pomocne jest zrozumienie, co się dzieje po naciśnięciu:

Większość powłok wiąże Ctrl+, Caby „wysłać sygnał SIGINT do programu, który obecnie działa na pierwszym planie”. Możesz przeczytać o różnych sygnałach za pomocą sygnału man :

 SIGINT        2       Term    Interrupt from keyboard

Programy mogą zignorować ten sygnał, ponieważ mogą również zignorować SIGTSTP :

 SIGTSTP   18,20,24    Stop    Stop typed at tty

(To właśnie robi większość powłok po naciśnięciu Ctrl+ Z, dlatego nie gwarantuje się, że zadziała).

Istnieje kilka sygnałów, których proces nie może zignorować: SIGKILL , SIGSTOP i niektóre inne. Możesz wysłać te sygnały za pomocą polecenia kill . Tak więc, aby zabić swój proces zawieszenia / zombie, po prostu znajdź identyfikator procesu (PID). Na przykład użyj pgreplub, psa następnie kill:

 % kill -9 PID
akira
źródło
13
Zwykła uwaga. Uważaj, że „zombie” jest technicznie stanem procesu i nie jest tym samym, co miałeś na myśli przez „zombie”. (Zakończony proces, który nie był oczekiwany () - wydany przez jego rodzica, jest w stanie zombie ( Z). W tym przypadku nie jest już w stanie obsłużyć sygnałów.)
Stéphane Gimenez
Niestety, czasami ctrl + c, ctrl + z, i ctrl + \ wszystko nic nie robi, a proces działa w trybie Cofnij sudo (dozwolone bez hasła), więc nie możesz po prostu wysłać sygnału do procesu.
Michael
112

Jeśli Ctrl+ C(SIGINT) nie działa, spróbuj Ctrl+ \(SIGQUIT). Następnie spróbuj Ctrl+ Z(SIGTSTP). Jeśli to spowoduje powrót do monitu powłoki, zrób to killna ID procesu. (Domyślnie jest to sygnał SIGTERM, który można określić z kill -TERM. W niektórych muszli, może być w stanie wykorzystać %1w odniesieniu do PID). Jeśli to nie zadziała, należy przejść do innej sesji terminala lub SSH i zrobienia killlub kill -TERMna identyfikator procesu. Powinieneś to zrobić w ostatecznościkill -KILL , alias kill -9, ponieważ nie daje to procesowi szansy na czyste przerwanie, zsynchronizowanie otwartych plików, usunięcie plików tymczasowych, zamknięcie połączeń sieciowych itp.

Miś
źródło
32

Naciśnij Ctrl-Z, aby zawiesić program i umieścić go w tle :

Suspend the program currently running and put it in the background.
This does not stop the process as it does in VMS!

(Przywróć ponownie na pierwszym planie za pomocą fg)

Następnie można killalbo kill -9to, biorąc pod uwagę jego identyfikator procesu (to masz od ps a).

Daniel Beck
źródło
13
Dzięki bash możesz kill $!, podobnie jak $!specjalna zmienna zawierająca pid ostatniego programu w tle.
Lloeki,
@Lloeki Nie działa dla mnie (przynajmniej nie jest wiarygodny). Muszę bgraz, zanim zmienna otrzyma przypisaną wartość.
Daniel Beck
2
@Daniel, poprawnie. Jest tak, jak powiedziałem, ostatni proces działający w tle , dlatego potrzebuje bgzaraz po Ctrl + Z tylko zawieszenia.
Lloeki
2
Uwaga: nie jest to tylko sztuczka, użycie pswyjścia (lub killall) jest dość ryzykowne, jeśli masz uruchomionych wiele procesów o tej samej nazwie. ps -e -o pid,commanddostarczy pid + pełne argumenty, nie tylko nazwę programu, ale znowu może nie wystarczyć do rozróżnienia. Natomiast $!jest pewnym hitem.
Lloeki,
1
@Lloeki Nie zgadzam się. Przykładowy wiersz wyjściowy z ps amojego systemu: 27721 s000 T 0:00.09 topIle zawieszonych ( Tjak sądzę) wystąpień tej samej komendy ( top) masz uruchomionych w tym samym tty ( s000)?
Daniel Beck
30

Zobacz także ten link .

Ctrl+ Z: wstrzymaj proces.

Ctrl+ C: uprzejmie poproś o zamknięcie procesu teraz.

Ctrl+ \: bezlitośnie zabij proces, który jest obecnie na pierwszym planie

RoboAlex
źródło
"ctrl"+ "\"nie działało dla mnie
Benyamin Jafari
13

Zwykle nadal można zatrzymać proces ( Ctrl+ Z), a następnie użyć kill -9. Ponieważ kill -9potrzebujesz najpierw PID procesu . W przypadku zadań w tle kill -9 %1jest to najłatwiejszy sposób - jeśli nie masz pewności, ile zadań w tle chcesz zabić, uruchom jobs.

Alternatywnie możesz znaleźć identyfikator procesu za pomocą

ps

Potem możesz biec

kill -9 <Appropriate PID from ps output>
Olli
źródło
5

Prostszym rozwiązaniem dla Bash (i innych powłok?) Jest:

Ctrl-z      followed by     kill -9 %1

gdzie „% 1” odnosi się do zabijanego zadania. Może to być „% 2” (lub coś innego), jeśli śpisz już w innej pracy. Możesz zobaczyć, jaki jest numer zadania po naciśnięciu Ctrl-z:

[1]+  Stopped                 <process name>

Zauważ, że „kill” to wersja kill powłoki, a nie / bin / kill.

Dustin Boswell
źródło
4

1) Jeśli jesteś w konsoli i jest w trybie wielu użytkowników, możesz nacisnąć CTRL-ALT-Fn i zalogować się na innym ekranie, użyć ps -ef | grep <myprocessname>lub, pidof <myprocessname>a następnie zabić -9 proces według numeru ID.

2) Jeśli łączysz się zdalnie, zrób to samo za pośrednictwem innej sesji terminala.

Możesz także ułatwić sobie życie, instalując htop , który jest bardziej uniwersalną wersją topu, która pozwala selektywnie zabijać uruchomione procesy. Większość dystrybucji ma htop w repozytorium.

3) jeśli utknąłeś w zawieszonej sesji ssh (na przykład w innym systemie), spróbuj nacisnąć tyldę (~), która jest klawiszem Escape, a następnie naciśnij CTRL-Z, aby wrócić do sesji hosta, a następnie może zabić zablokowany proces ssh lub poczekać, aż upłynie limit czasu, co większość parapetów robi po okresie bezczynności.

Linker3000
źródło
0

Jeśli używasz tmux lub screena i żadne z powyższych nie działa, nadal możesz zabić okienko <prefix> x, wtedy proces również zostanie zabity.

ospider
źródło
0

Być może w twoim / etc / profilu znajduje się zestaw pułapek z SIGINT (2). Jeśli tak, usuń go. Wyloguj się i zaloguj ponownie, a powinieneś być dobry.

TechNo_phile
źródło