Red Hat System Administration I 8.2

Завершение процессов

Задачи

После завершения этого раздела вы сможете:

  • выполнять команды для завершения процессов и установления связи с ними;

  • определять характеристики демона;

  • завершать пользовательские сеансы и процессы.

Управление процессами с помощью сигналов

Сигнал ― это программное прерывание, передаваемое процессу. Сигналы сообщают о событиях выполняющейся программе. Событиями, которые генерируют сигнал, могут быть ошибки или внешние события (например, запрос на ввод-вывод или истекшее время таймера). Это также может быть явное использование команды передачи сигнала или нажатие клавиш на клавиатуре.

В следующей таблице указаны основные сигналы, используемые системными администраторами для стандартного управления процессами. Сигналы указываются либо по их короткому (HUP), либо по собственному (SIGHUP) имени.

Таблица 8.2. Основные сигналы управления процессами

Номер сигналаКороткое имяОпределениеНазначение
1HUPПрерывание связи

Сообщает о завершении управляющего процесса терминала. Также используется для запроса повторной инициализации процесса (перезагрузка конфигурации) без его завершения.

2INTПрерывание с клавиатуры

Приводит к завершению программы. Может быть заблокирован или обработан. Передается нажатием сочетания клавиш INTR (Ctrl+c).

3QUITКлавиатурный выход

Аналогичен SIGINT. Добавляет дамп процесса при завершении. Передается нажатием сочетания клавиш QUIT (Ctrl+\).

9KILLЗавершить, не может быть заблокирован

Приводит к немедленному завершению программы. Не может быть заблокирован, игнорирован или обработан; всегда окончателен.

15 по умолчанию TERMЗавершить

Приводит к завершению программы. В отличие от SIGKILL, может быть заблокирован, игнорирован или обработан. «Корректный» способ отправки программе запроса на завершение; позволяет выполнить самоочистку.

18CONTПродолжить

Передается процессу для его возобновления, если он остановлен. Не может быть заблокирован. Даже если обработан, всегда возобновляет процесс.

19STOPОстановить, не может быть заблокирован

Приостанавливает процесс. Не может быть заблокирован или обработан.

20TSTPОстановка с клавиатуры

В отличие от SIGSTOP, может быть заблокирован, игнорирован или обработан. Передается нажатием сочетания клавиш SUSP (Ctrl+z).


Примечание

Номера сигналов различаются на различных аппаратных платформах Linux, но имена сигналов и их значения стандартизированы. В командах рекомендуется использовать имена сигналов, а не их номера. Номера, обсуждаемые в этом разделе, предназначены для систем x86_64.

Каждый сигнал имеет действие по умолчанию (обычно одно из следующих).

  • Term — вызывает немедленное завершение программы (выход из нее).

  • Core — вызывает сохранение программой образа памяти (дамп ядра), затем завершение.

  • Stop — вызывает прекращение выполнения программы (приостановку) и ожидает продолжения ее работы (возобновления).

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

Команды для передачи сигналов путем явного запроса

С помощью сочетаний клавиш можно отправить сигнал текущему активному процессу, чтобы приостановить процесс (Ctrl+z), завершить его (Ctrl+c) или сохранить дамп ядра (Ctrl+\). Однако вы будете использовать специальные команды для отправки сигналов фоновому процессу или процессам в другом сеансе.

Сигналы можно указывать в качестве опций по имени (например, -HUP или -SIGHUP) или по номеру (например, -1). Пользователи могут завершать (прерывать) свои собственные процессы, но для завершения процессов, принадлежащих другим пользователям, требуются права root.

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

[user@host ~]$ kill -l
 1) SIGHUP      2) SIGINT      3) SIGQUIT     4) SIGILL      5) SIGTRAP
 6) SIGABRT     7) SIGBUS      8) SIGFPE      9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT  17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
...output omitted...
[user@host ~]$ ps aux | grep job
5194  0.0  0.1 222448  2980 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job1
5199  0.0  0.1 222448  3132 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job2
5205  0.0  0.1 222448  3124 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job3
5430  0.0  0.0 221860  1096 pts/1    S+   16:41   0:00 grep --color=auto job
[user@host ~]$ kill 5194
[user@host ~]$ ps aux | grep job
user   5199  0.0  0.1 222448  3132 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job2
user   5205  0.0  0.1 222448  3124 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job3
user   5783  0.0  0.0 221860   964 pts/1    S+   16:43   0:00 grep --color=auto job
[1]   Terminated              control job1
[user@host ~]$ kill -9 5199
[user@host ~]$ ps aux | grep job
user   5205  0.0  0.1 222448  3124 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job3
user   5930  0.0  0.0 221860  1048 pts/1    S+   16:44   0:00 grep --color=auto job
[2]-  Killed                  control job2
[user@host ~]$ kill -SIGTERM 5205
user   5986  0.0  0.0 221860  1048 pts/1    S+   16:45   0:00 grep --color=auto job
[3]+  Terminated              control job3

Команда killall может отправлять сигналы нескольким процессам по имени команды.

[user@host ~]$ ps aux | grep job
5194  0.0  0.1 222448  2980 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job1
5199  0.0  0.1 222448  3132 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job2
5205  0.0  0.1 222448  3124 pts/1    S    16:39   0:00 /bin/bash /home/user/bin/control job3
5430  0.0  0.0 221860  1096 pts/1    S+   16:41   0:00 grep --color=auto job
[user@host ~]$ killall control
[1]   Terminated              control job1
[2]-  Terminated              control job2
[3]+  Terminated              control job3
[user@host ~]$ 

Используйте команду pkill, чтобы отправить сигнал одному или нескольким процессам, которые соответствуют критериям выбора. Критериями выбора могут быть имя команды, процесс, принадлежащий конкретному пользователю, или все системные процессы. Команда pkill поддерживает расширенные критерии выбора.

  • Команда — процессы с именем команды, соответствующим шаблону.

  • UID — процессы, принадлежащие учетной записи пользователя Linux, эффективной или реальной.

  • GID — процессы, принадлежащие учетной записи группы Linux, эффективной или реальной.

  • Родительский — дочерние процессы определенного родительского процесса.

  • Терминал — процессы, запущенные на конкретном управляющем терминале.

[user@host ~]$ ps aux | grep pkill
user   5992  0.0  0.1 222448  3040 pts/1    S    16:59   0:00 /bin/bash /home/user/bin/control pkill1
user   5996  0.0  0.1 222448  3048 pts/1    S    16:59   0:00 /bin/bash /home/user/bin/control pkill2
user   6004  0.0  0.1 222448  3048 pts/1    S    16:59   0:00 /bin/bash /home/user/bin/control pkill3
[user@host ~]$ pkill control
[1]   Terminated              control pkill1
[2]-  Terminated              control pkill2
[user@host ~]$ ps aux | grep pkill
user   6219  0.0  0.0 221860  1052 pts/1    S+   17:00   0:00 grep --color=auto pkill
[3]+  Terminated              control pkill3
[user@host ~]$ ps aux | grep test
user   6281  0.0  0.1 222448  3012 pts/1    S    17:04   0:00 /bin/bash /home/user/bin/control test1
user   6285  0.0  0.1 222448  3128 pts/1    S    17:04   0:00 /bin/bash /home/user/bin/control test2
user   6292  0.0  0.1 222448  3064 pts/1    S    17:04   0:00 /bin/bash /home/user/bin/control test3
user   6318  0.0  0.0 221860  1080 pts/1    S+   17:04   0:00 grep --color=auto test 
[user@host ~]$ pkill -U user
[user@host ~]$ ps aux | grep test
user   6870  0.0  0.0 221860  1048 pts/0    S+   17:07   0:00 grep --color=auto test
[user@host ~]$ 

Административный вывод пользователей из системы

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

Чтобы вывести пользователя из системы, сначала идентифицируйте нужный сеанс входа. Используйте команду w для отображения сеансов входа пользователей и текущих запущенных процессов. Просмотрите столбцы TTY и ОТ, чтобы определить сеансы, которые нужно закрыть.

Все сеансы входа пользователя связаны с терминальным устройством (TTY). Если имя устройства имеет вид pts/N, это псевдотерминал, связанный с окном графического терминала или сеансом удаленного входа. Если оно имеет вид ttyN, значит, пользователь находится на консоли системы, альтернативной консоли или другом, подключенном напрямую, терминальном устройстве.

[user@host ~]$ w
 12:43:06 up 27 min,  5 users,  load average: 0.03, 0.17, 0.66
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty2                      12:26   14:58   0.04s  0.04s -bash
bob      tty3                      12:28   14:42   0.02s  0.02s -bash
user     pts/1    desk.example.com 12:41    2.00s  0.03s  0.03s w
[user@host ~]$ 

Чтобы узнать, как долго пользователь был в системе, посмотрите время входа в систему для данного сеанса. Для каждого сеанса ресурсы ЦП, потребляемые текущими заданиями, включая фоновые задачи и дочерние процессы, указаны в столбце JCPU. Потребление ресурсов ЦП текущим активным процессом указано в столбце PCPU.

Процессы и сеансы могут получать сигналы индивидуально или коллективно. Чтобы завершить все процессы у одного пользователя, используйте команду pkill. Поскольку самый первый процесс в сеансе входа в систему (лидер сеанса) предназначен для обработки запросов прерывания сеанса и игнорирования непреднамеренных сигналов с клавиатуры, для завершения всех пользовательских процессов и регистрационных оболочек необходимо использовать сигнал SIGKILL.

Важно

Администраторы обычно несколько поспешно используют сигнал SIGKILL.

Поскольку сигнал SIGKILL не может быть обработан или проигнорирован, его результат всегда необратим. Он осуществляет прерывание, не позволяя завершенному процессу запустить процедуры самоочистки. Рекомендуется отправить сначала сигнал SIGTERM, а затем попробовать отправить SIGINT, и только если обе эти попытки будут неудачны, отправлять SIGKILL.

Сначала с помощью команды pgrep определите номера PID процессов, которые нужно завершить. Команда pgrep работает так же, как pkill, и поддерживает те же опции, но отображает, а не завершает процессы.

[root@host ~]# pgrep -l -u bob
6964 bash
6998 sleep
6999 sleep
7000 sleep
[root@host ~]# pkill -SIGKILL -u bob
[root@host ~]# pgrep -l -u bob
[root@host ~]# 

Если нужные процессы запущены в одном и том же сеансе входа, необходимости в завершении всех процессов пользователя может не быть. С помощью команды w определите управляющий терминал для сеанса, а затем завершите только те процессы, которые ссылаются на один и тот же идентификатор терминала. Если команда SIGKILL не используется, лидер сеанса (здесь регистрационная оболочка Bash) успешно обрабатывает запрос завершения и не удаляется, но все другие процессы сеанса завершаются.

[root@host ~]# pgrep -l -u bob
7391 bash
7426 sleep
7427 sleep
7428 sleep
[root@host ~]# w -h -u bob
bob      tty3      18:37    5:04   0.03s  0.03s -bash
[root@host ~]# pkill -t tty3
[root@host ~]# pgrep -l -u bob
7391 bash
[root@host ~]# pkill -SIGKILL -t tty3
[root@host ~]# pgrep -l -u bob
[root@host ~]# 

Такое же избирательное завершение процессов можно реализовать с помощью взаимосвязей родительского и дочернего процессов. Используйте команду pstree, чтобы просмотреть дерево процессов для одного пользователя или системы. Используйте PID родительского процесса, чтобы завершить все созданные им дочерние процессы. На этот раз родительская регистрационная оболочка Bash остается, так как сигнал направлен только на ее дочерние процессы.

[root@host ~]# pstree -p bob
bash(8391)─┬─sleep(8425)
           ├─sleep(8426)
           └─sleep(8427)
[root@host ~]# pkill -P 8391
[root@host ~]# pgrep -l -u bob
bash(8391)
[root@host ~]# pkill -SIGKILL -P 8391
[root@host ~]# pgrep -l -u bob
bash(8391)
[root@host ~]# 

Ссылки

info libc signal (Справочное руководство по библиотекам GNU C)

  • Раздел 24. Обработка сигналов

info libc processes (Справочное руководство по библиотекам GNU C)

  • Раздел 26. Процессы

Man-страницы kill(1), killall(1), pgrep(1), pkill(1), pstree(1), signal(7) и w(1)