Что делать, если Ctrl + C не может завершить процесс?

153

Ctrl + С не всегда работает, чтобы убить текущий процесс (например, если этот процесс занят определенными сетевыми операциями). В этом случае вы просто видите курсор «^ C» и больше ничего не можете сделать.

Какой самый простой способ заставить этот процесс умереть без потери моего терминала?

Резюме ответов: Обычно вы можете Ctrl + Z уложить процесс, а затем сделать kill -9 _process-pid_где вы найдете PID процесса с п.с. и другие инструменты. На удар (и, возможно, другие снаряды), вы можете сделать kill -9 %1 (или «% N» в целом), что проще. Если Ctrl + Z не работает, вам придется открыть другой терминал и убийство оттуда.

Dustin Boswell
источник
screen было бы возможным решением, позволяющим создать новое окно и kill процесс оттуда.
Bobby
2
при условии, что вы уже были на экране :)
Dustin Boswell

Ответы:

107

Чтобы понять проблему почему Ctrl + С не работает, очень полезно понять, что происходит при нажатии:

Большинство оболочек связывают Ctrl + С "отправить SIGINT Сигнал для программы, которая в настоящее время работает на переднем плане ". Вы можете прочитать о различных сигналах через сигнал человека :

 SIGINT        2       Term    Interrupt from keyboard

Программы могут игнорировать этот сигнал, так как они могут игнорировать SIGTSTP также:

 SIGTSTP   18,20,24    Stop    Stop typed at tty

(Что делает большинство оболочек, когда вы нажимаете Ctrl + Z , поэтому он не гарантированно работает.)

Есть некоторые сигналы, которые не могут быть проигнорированы процессом: SIGKILL , SIGSTOP и некоторые другие. Вы можете отправить эти сигналы через убийство команда. Итак, чтобы убить процесс зависания / зомби, просто найдите идентификатор процесса (ПИД). Например, используйте pgrep или же ps а потом kill Это:

 % kill -9 PID
akira
источник
13
Простое замечание. Остерегайтесь того, что «зомби» - это технически состояние процесса, и оно отличается от того, что вы подразумевали здесь под «зомбиингом». (Завершенный процесс, который не был wait () - его родительский процесс находится в зомби ( Z ) государство. В этом случае он больше не может обрабатывать сигналы.)
Stéphane Gimenez
увы, иногда ctrl + c, ctrl + z и ctrl + \ all ничего не делают, и процесс выполняется отменить sudo (разрешено без пароля), поэтому вы не можете просто отправить сигнал процессу.
Michael
102

Если Ctrl + С (SIGINT) не работает, попробуйте Ctrl + \ (SIGQUIT). Тогда попробуй Ctrl + Z (SIGTSTP). Если это возвращает вас к приглашению оболочки, выполните kill на идентификатор процесса. (По умолчанию используется сигнал SIGTERM, который можно указать с помощью kill -TERM, В некоторых оболочках вы можете использовать %1 чтобы обратиться к PID.) Если это не сработает, перейдите на другой терминал или сеанс SSH и выполните kill или же kill -TERM на идентификатор процесса. Только в крайнем случае если ты сделаешь kill -KILL, a.k.a. kill -9, поскольку он не дает процессу никакой возможности аккуратно прервать работу, синхронизировать открытые файлы, удалить временные файлы, закрыть сетевые подключения и т. д.

Teddy
источник
28

Нажмите Ctrl-Z, чтобы приостановить программу и поставить ее в фоновом режиме :

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

(Восстановить на передний план снова, используя fg )

Тогда ты можешь kill или же kill -9 это, учитывая его идентификатор процесса (вы получаете это от ps a ).

Daniel Beck
источник
12
С Bash вы можете kill $!, как $! это специальная переменная, содержащая pid последней фоновой программы.
Lloeki
@Lloeki не работает для меня (по крайней мере, не надежно). Мне пришлось bg один раз перед тем, как переменная получает присвоенное значение.
Daniel Beck
2
@ Даниэль, правильно. Это как я сказал последний справочная информация процесс, таким образом, потребности bg как сразу после Ctrl + Z это просто приостановлено.
Lloeki
2
Примечание: это не просто трюк, используя ps вывод (или killall ) довольно рискованно, если у вас запущено несколько процессов с одним и тем же именем. ps -e -o pid,command предоставит pid + полные аргументы, а не только имя программы, но опять же может быть недостаточно для различения. По сравнению $! это верный удар.
Lloeki
1
@Lloeki Я не согласен. Пример строки вывода из ps a в моей системе: 27721 s000 T 0:00.09 top Сколько приостановлено ( TЯ думаю) экземпляры одной и той же команды ( top ) у вас работает в том же tty ( s000 )?
Daniel Beck
26

Видеть это ссылка на сайт также.

Ctrl + Z : приостановить процесс.

Ctrl + С : вежливо попросить процесс закрыть сейчас.

Ctrl + \ : беспощадно убить процесс, который сейчас находится на переднем плане

RoboAlex
источник
"ctrl" + "\" не работал для меня
Benyamin Jafari
12

Обычно вы все равно можете остановить процесс ( Ctrl + Z ), а затем использовать kill -9, За kill -9вам нужно PID процесса первый. Для фоновых заданий, kill -9 %1 это самый простой способ сделать это - если вы не уверены, какое количество фоновых заданий вы хотите убить, запустите jobs,

Кроме того, вы можете найти идентификатор процесса с

ps

Тогда вы можете запустить

kill -9 <Appropriate PID from ps output>
Olli
источник
4

1) Если вы находитесь на консоли и в многопользовательском режиме, вы можете нажать CTRL-ALT-Fn и войти в систему на другом экране, используйте ps -ef | grep <myprocessname> или же pidof <myprocessname> а затем убить -9 процесс по номеру ID.

2) Если вы подключены удаленно, сделайте то же самое через другой сеанс терминала.

Вы также можете сделать жизнь немного проще, установив HTOP , которая является более универсальной версией top, которая позволяет выборочно уничтожать запущенные процессы. Большинство дистрибутивов имеют htop в репо.

3) если вы просто застряли в зависшем сеансе ssh (например, в другой системе), попробуйте нажать тильду (~), которая является клавишей escape, и затем нажмите CTRL-Z, чтобы вернуться к сеансу хоста, затем вы может убить застрявший процесс ssh или подождать, пока он истечет время ожидания, что большинство силов делает после периода бездействия.

Linker3000
источник
4

Более простое решение для Bash (и других оболочек?) Состоит в следующем:

Ctrl-z      followed by     kill -9 %1

где «% 1» относится к убиваемому номеру задания. Это может быть "% 2" (или что-то еще), если у вас уже спят другие задания. Вы можете увидеть, какой это номер задания, когда вы нажмете Ctrl-z:

[1]+  Stopped                 <process name>

Обратите внимание, что kill - это версия kill для оболочки, а не / bin / kill.

Dustin Boswell
источник
0

Если вы используете tmux или screen и ничего из вышеперечисленного не работает, вы все равно можете убить панель с помощью <prefix> xзатем процесс тоже убивается.

ospider
источник
0

Возможно, в вашем / etc / профиле установлена ​​ловушка с SIGINT (2). Если так, удалите это. Выйдите из системы и войдите снова, и вы должны быть хорошими.

TechNo_phile
источник