11

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

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

Благодарю вас.

8 ответов8

20

Ctrl-C отправляет SIGINT. По умолчанию это завершает приложение. Возможно, вы путаете это с Ctrl-Z, который приостанавливает приложение в bash.

7

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

  • SIGINT (Intettput) обычно 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, но это может быть не так, поскольку процесс может перехватить сигнал и проигнорировать его.

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

5

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

  1. Как говорили многие другие: Control-C обычно посылает сигнал Unix SIGINT, и поведение по умолчанию (из программ, которые не переопределяют его) - "завершить процесс". Программа может игнорировать этот сигнал или предпринимать другие действия, если того пожелает.
  2. Вы также можете отправить SIGQUIT с клавиатуры с помощью Control-\. Разница здесь в том, что по умолчанию процесс запишет файл ядра, а затем выйдет. Программа может игнорировать этот сигнал или предпринимать другие действия, если того пожелает.
  3. Чтобы завершить работу с предубеждением и не допуская остановки процесса, используйте SIGKILL, который по умолчанию не привязан ни к одному ключу. Вместо этого вы обычно отправляете его с помощью команды kill (1) и задаете сигнал для отправки, как в $ kill -9 или мнемонически $ kill -KILL Этот сигнал обрабатывается непосредственно ОС, и программа не может переопределить поведение по умолчанию
  4. Если ваша оболочка поддерживает управление заданиями, она также может поддерживать встроенную версию kill которая поддерживает идентификацию заданий с использованием символа % как в ответе подиума.
  5. Чтобы приостановить процесс возобновляемым способом, вы используете Control-z, который отправляет SIGTSTP. Вы возобновляете такой процесс либо с помощью fg для продолжения контроля над терминалом, либо с помощью bg чтобы установить его работу без сохранения контроля над терминалом (но по умолчанию все равно отправляете свои выходные данные туда).
1

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

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

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

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

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

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

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

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

0

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

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

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

0

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .