Завершение процесса в Unix вместо его прерывания


12

В Unixкомандной строке, если я нажимаю Ctrl-C, это не завершает процесс, а скорее прерывает его, и я возвращаюсь к приглашению оболочки.

Итак, у меня есть следующие два вопроса:

    1. Есть ли способ увидеть список всех прерванных процессов и завершить их?
    1. Какую комбинацию клавиш нажать, чтобы завершить процесс, а не прерывать его?

Ответы:


20

Ctrl+ Cотправляет SIGINT. По умолчанию это завершает приложение.

Вы путаете это с тем Ctrl-Z, что приложение в bash приостанавливается.


7

Исторически было три сигнала, связанных с нажатиями клавиш, это были

  • SIGINT (Прерывание) обычно Ctrl+ CилиDel
  • SIGQUIT - Выход - Обычно связан с Ctrl+\
  • SIGSUSP Suspend - обычно связан с Ctrl+Z

На некоторых разновидностях * nix есть и другие связанные сигналы, вы можете проверить привязки клавиатуры, используя команду

stty -a

В моей системе OS / X это выдает следующий вывод

speed 9600 baud; 65 rows; 213 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

Обратите внимание, что в этом случае kill не является сигналом KILL, это связано с очисткой текущего входного буфера.

Вы можете добиться большего успеха с остановкой процессов с использованием SIGQUIT, но это может быть не так, поскольку процесс может перехватить сигнал и проигнорировать его.

Не существует понятия списка «прерванных» процессов, поскольку процесс либо перехватил и проигнорировал прерывание, либо завершился. Вы можете получить список приостановленных процессов, набрав задание


Интересно, что я показываю ^ Q и ^ S (как и вы), но настроил stty -ixonтак, чтобы они были пропущены. Я думаю, что они изменятся на <undef>.
Приостановлено до дальнейшего уведомления.

Я не нахожу SIGSUSP на страницах man ни моего OS X-бокса, ни моего Debian Lenny-бокса. Вроде бы SIGTSTP.
dmckee --- котенок экс-модератора

DEL - ах, план 9 ...
new123456

5

Множество правильных ответов, но ни одного полного.

  1. Как говорили многие другие: Control-C обычно посылает сигнал Unix SIGINT, и поведение по умолчанию (из программ, которые его не переопределяют) - «завершить процесс». Программа может игнорировать этот сигнал или предпринимать иные действия, если того пожелает.
  2. Вы также можете отправить SIGQUIT с клавиатуры с помощью Control- \. Разница здесь в том, что по умолчанию процесс запишет файл ядра, а затем выйдет. Программа может игнорировать этот сигнал или предпринимать иные действия, если того пожелает.
  3. Чтобы завершить работу с предубеждением и не допуская остановки процесса, используйте SIGKILL, который по умолчанию не привязан ни к одному ключу. Вместо этого вы обычно отправляете его, используя kill (1)команду и указывая сигнал для отправки, как в

    $ kill -9 <process ID>
    

    или мнемонически

    $ kill -KILL <process ID>
    

    Этот сигнал обрабатывается непосредственно ОС, и программа не может переопределить поведение по умолчанию.

  4. Если ваша оболочка поддерживает управление заданиями, она также может поддерживать встроенную версию, killкоторая поддерживает идентификацию заданий с помощью %символа, как в ответе подиума .

  5. Чтобы приостановить процесс возобновляемым способом, вы используете Control-z, который отправляет SIGTSTP. Вы возобновляете такой процесс, либо fgпродолжая управлять терминалом, либо bgзапускать его без сохранения контроля над терминалом (но по умолчанию все равно отправляете свой вывод туда).

Кроме того, дамп ядра на SIGQUIT зависит от многих административных деталей. ulimit -c, coreadm (1M) в Solaris и т. д. Еще одно замечание - fg отправляет сигнал SIGCONT, который заставляет процесс возобновить свою работу.
Тадеуш А. Кадлубовски

1
  1. чтобы увидеть список фоновых процессов: jobs

    убить: kill %1(подставьте 1 с соответствующим идентификатором задания, как в jobsвыводе)

  2. смотрите здесь

1

Ctrl-C отправляет SIGINT, что по умолчанию приводит к завершению процесса, но может быть захвачено ( \bin shиспользуя trap).

SIGKILL - это необратимый сигнал убийства.

В третий раз я думаю, что это правильно: я проверил все по документам. Посмотрим.


SIGKILL не может быть пойман

Ага. Я уже исправил это ...
Чарльз Стюарт

1

Это не понятно большинству новичков в терминале, но если ваша проблема в том, что вы находитесь в интерактивной программе, и вы не можете понять, как выбраться из нее, довольно часто qэто происходит. Например, это ключ для выхода less, который man, помимо прочего , является программой, которую вы получаете при просмотре страниц.

Некоторые программы имеют другие сочетания клавиш для выхода. В vimили vi, используйте ESC:wq. В emacs, использовать Control-C Control-X. В nanoили pico, используйте Control-X. Обратите внимание, что в этих примерах есть тонкости, в частности, касающиеся того, сохраняют ли эти ярлыки какие-либо изменения, которые вы, возможно, внесли в файл, который вы редактируете.


Так какой же стандарт?
Pacerier

0

Многие процессы могут установить обработчик прерывания для перехвата сигнала прерывания, но те, которые не прерывают его по умолчанию.

Чтобы принудительно завершить процесс, вы можете отправить SIGQUIT (Ctrl- \).


SIGQUIT может быть пойман в ловушку, SIGKILL не может быть.
Чарльз Стюарт

1
@Charles: еще одно отличие состоит в том, что SIGQUIT по умолчанию сбрасывает ядро, а SIGKILL - нет.
Тадеуш А. Кадлубовски

0

Кажется, что другие ответы - вероятный сценарий, но также возможно, что вы выполняете сценарий, который неправильно обрабатывает его дочерние элементы. Недавно я столкнулся с похожим сценарием, где уничтожение сценария не приведет к уничтожению дочерних процессов этого сценария.

В общем, если вы попадаете в эту ситуацию, вам придется пересмотреть все процессы, которые вы запускаете. Вы должны просмотреть справочную страницу для PS. ( man ps) Мне особенно нравится использование ps auxwf, которое показывает отношения родитель / потомок между процессами. pstreeделает что-то подобное. Вы должны запустить это из другого терминала перед тем, как убить процесс, чтобы увидеть, как все выглядит в обычной ситуации, и определить дочерние процессы.

Если вы затем убьете (с помощью ^ C) этот основной процесс, снова проверьте вывод команды ps, чтобы увидеть, изменилось ли что-нибудь. Если дочерние процессы все еще существуют, вы можете убить их с помощью killкоманды. (см. man kill)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.