Linux&FreeBSD: команды kill, nohup – сигналы и управление процессами

Автор: | 18/08/2013

linux&bfreebsd_logoСигналы – это метод передачи данных от пользователя – процессам, либо от процессов – пользователю или ядру некоторых команд для управления этими процессами.

В примерах используется операционная система CentOS, но те же примеры корректно будут работать и во FreeBSD.

Полный список можно посмотреть введя команду:

# kill -l

Все сигналы начинаются с приставки SIG, однако её можно не использовать. К примеру, сигнал SIGHUP с номером 1 при помощи команды kill можно отправить тремя способами.

К примеру, у нас запущена задача ping:

# ps aux | grep ping
root      1305  0.0  0.0   4540   804 pts/0    S+   05:47   0:00 ping ya.ru

Отправим сигнал SIGHUP (отбой):

# kill -sighup 1305

Проверим состояние Ping:

# ping ya.ru
PING ya.ru (77.88.21.3) 56(84) bytes of data.
64 bytes from www.yandex.ru (77.88.21.3): icmp_seq=1 ttl=54 time=26.7 ms
64 bytes from www.yandex.ru (77.88.21.3): icmp_seq=2 ttl=54 time=26.6 ms
64 bytes from www.yandex.ru (77.88.21.3): icmp_seq=3 ttl=54 time=26.8 ms
Hangup

Ту же задачу можно выполнить, указав номер сигнала. Для SIGHUP (или просто HUP) это №1:

# ps aux | grep ping
root      1308  0.0  0.0   5436   912 pts/0    S+   05:48   0:00 ping ya.ru
# kill -1 1308

Или так:

# kill -hup 1311

Список наиболее часто используемых сигналов:

Имя

Описание

Можно перехватывать

Можно блокировать

Комбинация клавиш

1 HUP Hangup. Отбой Да Да
2 INT Interrupt. В случае выполнения простых команд вызывает прекращение выполнения, в интерактивных программах — прекращение активного процесса Да Да <Ctrl>+<C> или <Del>
3 QUIT Как правило, сильнее сигнала Interrupt Да Да <Ctrl>+<>
4 ILL Illegal Instruction. Центральный процессор столкнулся с незнакомой командой (в большинстве случаев это означает, что допущена программная ошибка). Сигнал отправляется программе, в которой возникла проблема Да Да
8 FPE Floating Point Exception. Вычислительная ошибка, например, деление на ноль Да Да
9 KILL Всегда прекращает выполнение процесса Нет Нет
11 SEGV Segmentation Violation. Доступ к недозволенной области памяти Да Да
13 PIPE Была предпринята попытка передачи данных с помощью конвейера или очереди FIFO, однако не существует процесса, способного принять эти данные Да Да
15 TERM Software Termination. Требование закончить процесс (программное завершение) Да Да
17 CHLD Изменение статуса порожденного процесса Да Да
18 CONT Продолжение выполнения приостановленного процесса Да Да
19 STOP Приостановка выполнения процесса Нет Нет
20 TSTP Сигнал останова, генерируемый клавиатурой. Переводит процесс в фоновый режим Да Да <Ctrl>+<Z>

Ещё для примера – сигнал SIGTERM (TERM), №15:

# kill -15 1314
# ping ya.ru
PING ya.ru (77.88.21.3) 56(84) bytes of data.
Terminated

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

Для процессов, которые могут блокировать сигналы типа STOP или TERM имеется специальный сигнал KILL, который всегда приводит к уничтожению процесса, так как его невозможно перехватить и/или игнорировать.

Для примера – запустим ping с помощью команды nohup:

# nohup ping ya.ru
nohup: ignoring input and appending output to `nohup.out'

# ps aux | grep ping
root      1318  0.1  0.0   4544   916 pts/0    S+   05:56   0:00 ping ya.ru

И попробуем ему отправить сигнал HUP (отбой):

# kill -1 1318

Проверим:

# ps aux | grep ping
root      1318  0.0  0.0   4544   920 pts/0    S+   05:56   0:00 ping ya.ru

Процесс продолжает выполняться. Отправим ему сигнал KILL:

# kill -9 1318

# ps aux | grep ping
root      1326  0.0  0.0   4356   748 pts/1    S+   05:59   0:00 grep ping

Процесса “убит”. Посмотрим в консоли, где выполнялся ping:

# nohup ping ya.ru
nohup: ignoring input and appending output to `nohup.out'
Killed

Стоит отметить особенности работы процессов, запущенных с помощью команды nohup. Все выводимые данные отправляются не на стандартный вывод (stdout или stderr), а записываются в файл nohup.out, который создаётся в том каталоге, в котором находился пользователь, запустивший программу. В случае, если в этом 4каталоге создать файл невозможно – он будет создан в домашнем каталоге пользователя. Если не будет и такой возможности – команда выполнена не будет. Например – если у пользователя, запускающего nohup нет прав записи в файл:

$ ls -l  | grep nohup
-r--------. 1 setevoy setevoy 151393 Aug 18 06:46 nohup.out
$ nohup ping ya.ru
nohup: failed to open `nohup.out': Permission denied
nohup: failed to open `/home/setevoy/nohup.out': Permission denied

Кроме того, nohup продолжит выполнять программу даже после выхода пользователя из системы, т.е. – проигнорирует сигнал TERM, который передаст ему командный интерпретатор при завершении сессии пользователя. Однако, это не значит что процесс будет выполняться в фоном режиме – для этого его необходимо запускать со знаком &:

$ nohup ping ya.ru &

Дополнительная информация о nohup есть в статье UNIX: PID, PPID и nohup

Посмотрим, как этой действует. Допустим, у нас открыты два терминала:

# w
06:11:33 up 36 min,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
setevoy  pts/0    192.168.1.100    05:35    0.00s  0.34s  0.26s sshd: setevoy [priv]
setevoy  pts/1    192.168.1.100    06:11    3.00s  0.04s  0.04s -bash

На одном из них мы запустим тот же ping с помощью nohup:

$ nohup ping ya.ru
nohup: ignoring input and appending output to `nohup.out'

Вернёмся в первое окно:

# w
06:13:00 up 38 min,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
setevoy  pts/0    192.168.1.100    05:35    0.00s  0.27s  0.26s sshd: setevoy [priv]
setevoy  pts/1    192.168.1.100    06:11    6.00s  0.08s  0.03s ping ya.ru

Как видно – пользователь setevoy на терминале pts/1 выполняет команду ping.

Теперь – проверим его наличие в процессах:

# ps aux | grep ping
setevoy   1408  0.0  0.0   4544   916 pts/1    S+   06:12   0:00 ping ya.ru

Теперь – попросту завершим работу второго терминала:

# skill -9 -v pts/1
pts/1    setevoy   1373 bash

И проверим состояние процесса ping, запущенного setevoy:

# ps aux | grep ping
setevoy   1408  0.0  0.0   4544   916 ?        S    06:12   0:00 ping ya.ru

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