Differences between revisions 1 and 14 (spanning 13 versions)
Revision 1 as of 2011-10-24 16:03:03
Size: 6450
Editor: GreyCat
Comment:
Revision 14 as of 2014-09-16 03:48:15
Size: 297
Editor: BNia
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#pragma section-numbers 2
= Sending and Trapping Signals =

<<TableOfContents>>

Signals are a basic tool for asynchronous interprocess communication. What that means is one process (A) can tell another process (B) to do something, at a time chosen by process A rather than process B. (Compare to process B looking for a file every few seconds; this is called polling, and the timing is controlled by process B, rather than process A.)

The operating system provides a finite number of signals which can be "sent" to tell a process to do something. The signals do not carry any additional information; the only information the process gets is which signal was received. The process does not even know who sent the signal.

Unless a process takes special action in advance, most signals are fatal; that is, the default action a process will perform upon receiving a signal is an immediate exit. (Exceptions: SIGCHLD is ignored by default, SIGSTOP pauses the process, and SIGCONT resumes the process.) Some signals (such as SIGQUIT) also cause a process to leave a core file, in addition to exiting.

== Traps, or Signal Handlers ==

A process may choose to perform a different action, rather than exiting, upon receiving a signal. This is done by setting up a ''signal handler'' (or ''trap''). The trap must be set before the signal is received. A process that receives a signal for which it has set a trap is said to have ''caught'' the signal.

The simplest signal handling a process can choose to perform is to ''ignore'' a signal. This is generally '''a bad idea''', unless it is done for a very specific purpose. Ignoring signals often leads to ''runaway processes'' which consume all available CPU.

More commonly, traps can be set up to intercept a fatal signal, perform cleanup, and then exit gracefully. For example, a program that creates temporary files might wish to remove them before exiting. If the program is forced to exit by a signal, it won't be able to remove the files unless it catches the signal.

In a shell script, the command to set up a signal handler is `trap`. The `trap` command has 5 different ways to be used:

 * `trap 'some code' signal list` -- using this form, a signal handler is set up for each signal in the list. When one of these signals is received, the commands in the first argument will be executed.
 * `trap '' signal list` -- using this form, each signal in the list will be ignored. Most scripts should not do this.
 * `trap - signal list` -- using this form, each signal in the list will be restored to its default behavior.
 * `trap signal` -- using this form, the one signal listed will be restored to its default behavior. (This is legacy syntax.)
 * `trap` -- with no arguments, print a list of signal handlers.

Signals may be specified using a number, or using a symbolic name. The symbolic name is greatly preferred for POSIX or Bash scripts, because the mapping from signal numbers to actual signals can vary slightly across operating systems. For Bourne shells, the numbers may be required.

There is a core set of signals common to all Unix-like operating systems whose numbers realistically never change; the most common of these are:

|| Name || Number || Meaning ||
|| HUP || 1 || Hang Up. The controlling terminal has gone away. ||
|| INT || 2 || Interrupt. The user has pressed the interrupt key (usually Ctrl-C or DEL). ||
|| QUIT || 3 || Quit. The user has pressed the quit key (usually Ctrl-\). Exit and dump core. ||
|| KILL || 9 || Kill. This signal cannot be caught or ignored. Unconditionally fatal. No cleanup possible. ||
|| TERM || 15 || Terminate. This is the default signal sent by the `kill` command. ||
|| EXIT || N/A || Not really a signal. In a shell script, an EXIT trap is run on any exit, signalled or not. ||

The names used in a shell script lack the leading `SIG` portion. SIGHUP is trapped by using `trap ... HUP` and is sent by using `kill -HUP process_ID`. The special name EXIT is defined by POSIX and is preferred for any signal handler that simply wants to clean up upon exiting, rather than doing anything complex.

If you are asking a program to terminate, you should always use SIGTERM (simply `kill process_ID`). This will give the program a chance to catch the signal and clean up. If you use SIGKILL, the program cannot clean up, and may leave files in a corrupted state.

Please see ProcessManagement for a more thorough explanation of how processes work and interact.

== Examples ==

This is the basic method for setting up a trap to clean up temporary files:

{{{#!highlight sh
#!/bin/sh
tempfile=$(mktemp)
trap 'rm -f "$tempfile"' EXIT
...
}}}

This example defines a signal handler that will re-read a configuration file on SIGHUP. This is a common technique used by long-running daemon processes, so that they do not need to be restarted from scratch when a configuration variable is changed.
{{{#!highlight sh
#!/bin/sh
config=/etc/myscript/config
test -r "$config" && . "$config"
trap 'test -r "$config" && . "$config"' HUP
while true; do
  ...
}}}

== Special Note On SIGINT ==

If you choose to set up a handler for SIGINT (rather than using the EXIT trap), you should be aware that a process that exits in response to SIGINT [[http://www.cons.org/cracauer/sigint.html|should kill itself with SIGINT]] rather than simply exiting, to avoid causing problems for its caller. Thus:

{{{
trap 'rm -f "$tempfile"; trap - INT; kill -INT $$' INT
}}}

We can see the difference between a properly behaving process and a misbehaving process. On most operating systems, `ping` is an example of a misbehaving process. It traps SIGINT in order to display a summary at the end, before exiting. But it fails to kill itself with SIGINT, and so the calling shell does not know that it should abort as well. For example,

{{{
# Bash. Linux ping sytnax.
for i in {1..254}; do
  ping -c 2 192.168.1.$i
done
}}}

Here, if the user presses Ctrl-C during the loop, it will terminate the current `ping` command, but it will ''not'' terminate the loop. This is because Linux's `ping` command does not kill itself with SIGINT in order to communicate to the caller that the SIGINT was fatal. (Linux is not unique in this respect; I do not know of any operating system whose `ping` command exhibits the correct behavior.)

----
CategoryShell
40 year old Blacksmith Andrea Robichaux from Thetford Mines, has pastimes for instance going to movies, Samsung,nokia,sony Xperia,iphone, and collecting. Gains inspiration by going to Sian Ka'an.<<BR>>
<<BR>>
Here is my homepage :: Sony Xperia Z1 Vs Nokia Lumia 1020 Vs LG G2 Vs Samsung Galaxy

40 year old Blacksmith Andrea Robichaux from Thetford Mines, has pastimes for instance going to movies, Samsung,nokia,sony Xperia,iphone, and collecting. Gains inspiration by going to Sian Ka'an.

Here is my homepage :: Sony Xperia Z1 Vs Nokia Lumia 1020 Vs LG G2 Vs Samsung Galaxy

SignalTrap (last edited 2023-09-21 20:57:38 by 71)