Linux. Команда trap

06.05.2018

Теги: BashCLIКоманда

Сигналы — это числовые сообщения, которые посылаются запущенным приложениям операционной системой, другими приложениями или пользователем. Сигналы, как правило, ожидают от приложения какой-то определённой реакции, например «корректно завершить работу», «приостановить работу» или «умри!».

Обычно для отправки сигналов приложениям используется программа kill, но некоторые сигналы можно отправлять и при помощи клавиатурных комбинаций, например Ctrl+C или Ctrl+Z.

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

Могут быть ситуации, когда нежелательно, чтобы пользователи прерывали работу сценария, например с помощью Ctrl+C. Поскольку нужно освободить входной поток или удалить временные файлы. Команда trap позволяет перехватить сигнал до того, как он удалит процесс и выполнить некоторое дополнительное или альтернативное действие.

$ trap действие сигнал(ы)

Команда trap работает довольно просто — при возникновении сигнала будет выполнено указанное действие. Если действие простое (цепочка команд, умещающаяся на одной строке), его можно указать прямо в аргументе trap. Если не очень простое, то надо объявить функцию и поместить вызов этой функции в trap.

Если действие по умолчанию для сигнала было изменено с помощью trap, его можно восстановить с помощью все той же команды trap — надо опустить первый аргумент или заменить его дефисом:

$ trap сигнал(ы)
$ trap - сигнал(ы)

Для игнорирования сигналов команде trap надо передать пустую строку в качестве первого аргумента. Скрипт ниже можно прервать только смертоносным сигналом SIGKILL:

#!/bin/bash
trap '' SIGHUP SIGINT SIGQUIT SIGTERM
sleep 60

Вызов trap без аргументов напечатает все установленные обработчики сигналов, это полезно при отладке.

Сигналы

  • Сигнал SIGHUP (номер 1) изначально был предназначен для того, чтобы информировать программу о потере связи с управляющим терминалом. Этот сигнал посылается процессам и в случае закрытия виртуальных терминалов, которые используются на современных системах вместо аппаратных терминалов. Обычным действием по умолчанию для SIGHUP является перечитывание конфигурации без остановки.
  • Сигнал SIGINT (номер 2) посылается процессу, если пользователь терминала дал команду прервать процесс (обычно это сочетание клавиш Ctrl+C).
  • Сигнал SIGQUIT (номер 3) посылается процессу, если пользователь терминала дал команду остановить процесс комбинацией «quit» (обычно это сочетание клавиш Ctrl+\). Этот сигнал также указывает, что система должна выполнить дамп памяти для процесса.
  • Сигнал SIGKILL (номер 9) завершает работу программы. Программа не может ни обработать, ни игнорировать этот сигнал.
  • Сигнал SIGPIPE (номер 13) посылается процессу при записи в соединение (pipe, socket) при отсутствии или обрыве соединения с другой (читающей) стороной.
  • Сигнал SIGTERM (номер 15) вызывает «вежливое» завершение программы. Получив этот сигнал, программа может выполнить необходимые перед завершением операции (например, высвободить занятые ресурсы). Получение SIGTERM свидетельствует не об ошибке в программе, а о желании ОС или пользователя завершить ее.
  • Сигнал SIGCONT (номер 18) возобновляет выполнение процесса, остановленного сигналом SIGSTOP или сигналом SIGTSTP.
  • Сигнал SIGSTOP (номер 19) приостанавливает выполнение процесса. Как и SIGKILL, этот сигнал невозможно перехватить или игнорировать.
  • Сигнал SIGTSTP (номер 20) приостанавливает процесс по команде пользователя (обычно это сочетание клавиш Ctrl+Z). Для возобновления выполнения используется сигнал SIGCONT.

Список всех сигналов

$ 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
21) SIGTTIN       22) SIGTTOU       23) SIGURG        24) SIGXCPU       25) SIGXFSZ
26) SIGVTALRM     27) SIGPROF       28) SIGWINCH      29) SIGIO         30) SIGPWR
31) SIGSYS        34) SIGRTMIN      35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
43) SIGRTMIN+9    44) SIGRTMIN+10   45) SIGRTMIN+11   46) SIGRTMIN+12   47) SIGRTMIN+13
48) SIGRTMIN+14   49) SIGRTMIN+15   50) SIGRTMAX-14   51) SIGRTMAX-13   52) SIGRTMAX-12
53) SIGRTMAX-11   54) SIGRTMAX-10   55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
63) SIGRTMAX-1    64) SIGRTMAX

Примеры

Сценарий будет выполняться до тех пор, пока не получит сигнал SIGINT (нажатие Ctrl+C):

#!/bin/bash
count=0
trap 'echo "Получен сигнал SIGINT (нажатие Ctrl+C), завершение сценария"; exit 1' SIGINT
while true ; do
    sleep 1
    (( count++ ))
    echo $count
done

Удаление временного файла с помощью функции, которая передается в качестве первого аргумента команде trap:

#!/bin/bash

cleanup() {
    rm $TEMP_FILE
    exit $?
}

TEMP_FILE=/tmp/tempfile.$$.$RANDOM
trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM

# Делаем что-то...

Поиск: Bash • CLI • SIGCONT • SIGHUP • SIGINT • SIGKILL • SIGQUIT • SIGSTOP • SIGTERM • SIGTSTP • trap • Команда • Сигнал

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.