Linux trap all signals

Unix / Linux — Signals and Traps

In this chapter, we will discuss in detail about Signals and Traps in Unix.

Signals are software interrupts sent to a program to indicate that an important event has occurred. The events can vary from user requests to illegal memory access errors. Some signals, such as the interrupt signal, indicate that a user has asked the program to do something that is not in the usual flow of control.

The following table lists out common signals you might encounter and want to use in your programs −

Signal Name Signal Number Description
SIGHUP 1 Hang up detected on controlling terminal or death of controlling process
SIGINT 2 Issued if the user sends an interrupt signal (Ctrl + C)
SIGQUIT 3 Issued if the user sends a quit signal (Ctrl + D)
SIGFPE 8 Issued if an illegal mathematical operation is attempted
SIGKILL 9 If a process gets this signal it must quit immediately and will not perform any clean-up operations
SIGALRM 14 Alarm clock signal (used for timers)
SIGTERM 15 Software termination signal (sent by kill by default)

List of Signals

There is an easy way to list down all the signals supported by your system. Just issue the kill -l command and it would display all the supported signals −

The actual list of signals varies between Solaris, HP-UX, and Linux.

Default Actions

Every signal has a default action associated with it. The default action for a signal is the action that a script or program performs when it receives a signal.

Some of the possible default actions are −

Terminate the process.

Ignore the signal.

Dump core. This creates a file called core containing the memory image of the process when it received the signal.

Stop the process.

Continue a stopped process.

Sending Signals

There are several methods of delivering signals to a program or script. One of the most common is for a user to type CONTROL-C or the INTERRUPT key while a script is executing.

When you press the Ctrl+C key, a SIGINT is sent to the script and as per defined default action script terminates.

The other common method for delivering signals is to use the kill command, the syntax of which is as follows −

Here signal is either the number or name of the signal to deliver and pid is the process ID that the signal should be sent to. For Example −

The above command sends the HUP or hang-up signal to the program that is running with process ID 1001. To send a kill signal to the same process, use the following command −

This kills the process running with process ID 1001.

Trapping Signals

When you press the Ctrl+C or Break key at your terminal during execution of a shell program, normally that program is immediately terminated, and your command prompt returns. This may not always be desirable. For instance, you may end up leaving a bunch of temporary files that won’t get cleaned up.

Trapping these signals is quite easy, and the trap command has the following syntax −

Here command can be any valid Unix command, or even a user-defined function, and signal can be a list of any number of signals you want to trap.

There are two common uses for trap in shell scripts −

  • Clean up temporary files
  • Ignore signals

Cleaning Up Temporary Files

As an example of the trap command, the following shows how you can remove some files and then exit if someone tries to abort the program from the terminal −

Читайте также:  Run openvpn as service linux

From the point in the shell program that this trap is executed, the two files work1$$ and dataout$$ will be automatically removed if signal number 2 is received by the program.

Hence, if the user interrupts the execution of the program after this trap is executed, you can be assured that these two files will be cleaned up. The exit command that follows the rm is necessary because without it, the execution would continue in the program at the point that it left off when the signal was received.

Signal number 1 is generated for hangup. Either someone intentionally hangs up the line or the line gets accidentally disconnected.

You can modify the preceding trap to also remove the two specified files in this case by adding signal number 1 to the list of signals −

Now these files will be removed if the line gets hung up or if the Ctrl+C key gets pressed.

The commands specified to trap must be enclosed in quotes, if they contain more than one command. Also note that the shell scans the command line at the time that the trap command gets executed and also when one of the listed signals is received.

Thus, in the preceding example, the value of WORKDIR and $$ will be substituted at the time that the trap command is executed. If you wanted this substitution to occur at the time that either signal 1 or 2 was received, you can put the commands inside single quotes −

Ignoring Signals

If the command listed for trap is null, the specified signal will be ignored when received. For example, the command −

This specifies that the interrupt signal is to be ignored. You might want to ignore certain signals when performing an operation that you don’t want to be interrupted. You can specify multiple signals to be ignored as follows −

Note that the first argument must be specified for a signal to be ignored and is not equivalent to writing the following, which has a separate meaning of its own −

If you ignore a signal, all subshells also ignore that signal. However, if you specify an action to be taken on the receipt of a signal, all subshells will still take the default action on receipt of that signal.

Resetting Traps

After you’ve changed the default action to be taken on receipt of a signal, you can change it back again with the trap if you simply omit the first argument; so −

This resets the action to be taken on the receipt of signals 1 or 2 back to the default.

Источник

Linux trap and onitr command

On Unix-like operating systems, the trap command is a function of the shell that responds to hardware signals and other events.

This page covers the bash built-in version of trap.

Description

trap defines and activates handlers to run when the shell receives signals or other special conditions.

ARG is a command to be read and executed when the shell receives the signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC is supplied) or ARG is a dash (««), each specified signal is reset to its original value. If ARG is the null string, each SIGNAL_SPEC is ignored by the shell and by the commands it invokes.

If a SIGNAL_SPEC is EXIT (0), ARG is executed upon exit from the shell.

If a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.

If a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a script run by the «.» or source built-in commands finishes executing.

A SIGNAL_SPEC of ERR means to execute ARG each time a command’s failure would cause the shell to exit when the -e option is enabled.

If no arguments are supplied, trap prints the list of commands associated with each signal.

Syntax

Options

-l Print a list of signal names and their corresponding numbers.
-p Display the trap commands associated with each SIGNAL_SPEC.
Читайте также:  Порядок обновлений mac os

Examples

Display a list of signal names and their corresponding numbers. The list resembles the following:

Display a list of the currently-set signal traps.

Set a trap which, on shell error or shell exit, deletes a temporary file xyz$$.

csh — The C shell command interpreter.
exit — Exit the command shell.
ksh — The Korn shell command interpreter.
sh — The Bourne shell command interpreter.

Источник

LaurVas

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

Можно обрабатывать стандартные сигналы (их полный список выводится по trap -l ). Также доступны специфические для Bash: DEBUG , RETURN , ERR , EXIT .

На практике trap оказывается не такой уж простой штукой. Дьявол как всегда кроется в деталях. Сейчас покажу.

Изучаем trap на простых примерах

Ко мне понимание пришло одновременно с этим демонстрационным скриптом:

Скрипт выводит “start”, спит одну минуту, затем выводит “end”. Если во время сна поступает один из обрабатываемых сигналов, то просто выводится соответствующее сообщение.

Вывод реального терминала выглядит несколько иначе, я скрыл несущественные детали. Поясню что здесь происходило. Я запускал скрипт в фоне ( & после команды), затем командой kill посылал сигнал только что запущенному процессу. Чтобы послать SIGINT , не обязательно связываться с kill , можно во время работы скрипта нажать Ctrl + C .

Если убрать из скрипта обработку прерывающих сигналов, то будет уже не так. SIGINT , SIGHUP , SIGTERM не создают сигнал ERR , а сразу ведут на выход:

SIGQUIT создаёт ERR , но на выход не ведёт. Никакой закономерности тут нет, просто так работают дефолтные обработчики сигналов. У каждого сигнала своя специфика.

Для игнорирования сигналов используется пустой trap . Этот демонстрационный скрипт можно прервать только смертоносным сигналом SIGKILL .

Вернуть дефолтный обработчик сигнала тоже можно, пусть и не совсем очевидным способом:

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

Переменные внутри trap

Можно по-разному запихивать переменные внутрь trap . Здесь я использую ls , чтобы продемонстрировать обработку пробелов и false для имитации возникновения ошибки. Обратите внимание на кавычки.

Если вам непонятно почему так происходит, попробуйте запустить эти примеры с включенной опцией xtrace. Для этого добавьте в начале скрипта set -x или set -o xtrace . Или укажите в sha-bang’е bash -x . Или запускайте скрипты командой bash -x СКРИПТ .

Trap и функции

Наследует ли функция обработчики сигналов? Если да, то в какой момент: при вызове функции или при её объявлении?

Из выхлопа видно, что функция наследует обработчики сигналов в момент вызова. В противном случае trap первой функции был бы пустой.

Внимательные читатели заметили странное поведение обработчиков ERR и RETURN: они не наследуются! Чтобы получить обработку этих сигналов внутри функции, надо включить bash-опцию errtrace или объявить их явно в теле функции. Попробуйте сами.

Всё становится ещё запутаннее, если объявить функцию, которая выполняется в подоболочке (subshell). Этот пример отличается от предыдущего заменой фигурных скобочек на круглые:

Видим такое же поведение: наследуются все обработчики кроме ERR и RETURN. Однако если объявить какой-либо trap внутри функции, то наследование пропадает полностью!

А как bash ведёт себя в обратной ситуации? Попадают ли обработчики сигналов из функций наружу? Да, если функция была объявлена без подоболочки. Пруф:

Надеюсь эти примеры внесли ясность, а не запутали вас ещё больше.

Практическое применение trap

В реальной жизни вам вряд ли придётся писать такие запутанные обработчики. Обычно всё сводится к двум сценариям.

Блокировка скрипта lock-файлом:

Удаление временных файлов и подчистка за собой.

Простой однострочный вариант:

С использованием функции:

К сожалению эта система не даёт 100% надёжности. Trap сработает при завершении скрипта любым из стандартных способов:

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

но не сработает, если:

  • скрипт был убит сигналом SIGKILL,
  • пришёл OOM-killer и убил ваш процесс,
  • у компьютера внезапно отобрали питание.
Читайте также:  Установить атрибуты файлу linux

Ограничения

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

А если с подоболочкой? То же самое. Скорее всего так было сделано чтобы избежать зацикливания.

Источник

Linux trap all signals

List active traps for the current shell

Set a trap to execute commands when one or more signals are detected

Remove active traps

SYNOPSIS

PROLOG

This manual page is part of the POSIX Programmer’s Manual. The Linux implementation of this interface may differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface may not be implemented on Linux.

DESCRIPTION

If the first operand is an unsigned decimal integer, the shell shall treat all operands as conditions, and shall reset each condition to the default value. Otherwise, if there are operands, the first is treated as an action and the remaining as conditions.

If action is ‘-‘, the shell shall reset each condition to the default value. If action is null ( «вЂЉ»), the shell shall ignore each specified condition if it arises. Otherwise, the argument action shall be read and executed by the shell when one of the corresponding conditions arises. The action of trap shall override a previous action (either default action or one explicitly set). The value of «$?» after the trap action completes shall be the value it had before trap was invoked.

The condition can be EXIT, 0 (equivalent to EXIT), or a signal specified using a symbolic name, without the SIG prefix, as listed in the tables of signal names in the header defined in the Base Definitions volume of POSIX.1‐2017, Chapter 13, Headers; for example, HUP, INT, QUIT, TERM. Implementations may permit names with the SIG prefix or ignore case in signal names as an extension. Setting a trap for SIGKILL or SIGSTOP produces undefined results.

The environment in which the shell executes a trap on EXIT shall be identical to the environment immediately after the last command executed before the trap on EXIT was taken.

Each time trap is invoked, the action argument shall be processed in a manner equivalent to:

Signals that were ignored on entry to a non-interactive shell cannot be trapped or reset, although no error need be reported when attempting to do so. An interactive shell may reset or catch signals ignored on entry. Traps shall remain in place for a given shell until explicitly changed with another trap command.

When a subshell is entered, traps that are not being ignored shall be set to the default actions, except in the case of a command substitution containing only a single trap command, when the traps need not be altered. Implementations may check for this case using only lexical analysis; for example, if `trap` and $( trap — ) do not alter the traps in the subshell, cases such as assigning var=trap and then using $($var) may still alter them. This does not imply that the trap command cannot be used within the subshell to set new traps.

The trap command with no operands shall write to standard output a list of commands associated with each condition. If the command is executed in a subshell, the implementation does not perform the optional check described above for a command substitution containing only a single trap command, and no trap commands with operands have been executed since entry to the subshell, the list shall contain the commands that were associated with each condition immediately before the subshell environment was entered. Otherwise, the list shall contain the commands currently associated with each condition. The format shall be:

The shell shall format the output, including the proper use of quoting, so that it is suitable for reinput to the shell as commands that achieve the same trapping results. For example:

XSI-conformant systems also allow numeric signal numbers for the conditions corresponding to the following signal names:

Источник

Оцените статью