Guide to Unix/Explanations/Signals

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Signals[edit | edit source]

Signals are software interrupts that notify processes that some condition or event has occurred. Examples of events that generate signals are:

  • a process attempts a divide by zero
  • a user presses the INTERRUPT key at the terminal
  • a process sends another process a signal with the kill command of the kill function

A list of all the different signals can be displayed using

$ kill -l

The kill command can also be used to send signals to other processes. Start a background process that sleeps for 1000 seconds:

$ sleep 1000 &
[1]     14936
$ ps
 14936 pts/7    0:00 sleep
 12203 pts/7    0:01 bash

Note that the process id will (most likely) be different when you run it. The command-line below sends the SIGKILL signal to process 14936 (in this case):

$ kill -KILL 14936
$ ps
 12203 pts/7    0:01 ksh
[1] + Killed                   sleep 1000 &

Upon receiving the SIGKILL signal the sleep process terminates.

Traps[edit | edit source]

Processes can respond to signals in three different ways:

  • perform the default action
  • ignore the signal.
  • execute a specified function (called a signal handler)

The default action performed by a process when it receives a signal depends on the signal type. Most (like SIGKILL) cause the process to terminate. Others like SIGQUIT cause the process to terminate and generate a core dump:

$ sleep 1000 &
[1]     14950
$ kill -QUIT 14950
$ ps
 12203 pts/7    0:01 bash
[1] + Quit(coredump)           sleep 1000 &
$ ls core

Core files can be large so delete it:

$ rm core

Signals can be caught using the trap command. Create the following shell script in the file

trap 'echo "GOTCHA!"' INT KILL
while :
do sleep 10

Run in background:

$ &
[1]     15053
$ kill -INT 15053

The signal was caught and instead of terminating (which is the default action for SIGINT) the message "GOTCHA!" was echoed to standard output.

Some signals however can't be caught, SIGKILL for example:

$ kill -KILL 15053
[1] + Killed                   catch_signal &

Run; in foreground:

$ catch_signal

Hit the interrupt key (control-C usually):


Now hit the quit key:

^\catch_signal[3]: 15102 Quit(coredump)
$ ls core # will have generated a core file

Nohup[edit | edit source]

Commands run with nohup do not terminate when the user logs off.

Create the script in the file and make it executable:


while :
    sleep 100

Run it in background preceded by the command nohup:

$ nohup &
[1]     15224
Sending output to nohup.out

Check its running: id (12203 in this case):

$ ps -fu aholt
aholt 15224 12203 pts/7  sh ./
aholt 15232 15224 pts/7  sleep 100

Make a note of the parent process id (12203 in this case) of "dont_hangup" and the terminal device and log out of your session.

Log back in again. See that is still running:

$ ps -fu aholt
aholt 15224      1 ? 0:00 sh ./
aholt 15237 15224  ? 0:00 sleep 100

While "" is still running, its parent process has changed. The process id of the parent is 1 (not 12203 as before) and it is no longer associated with a terminal device. Using nohup is equivalent to ignoring the SIGHUP, that is:

trap '' HUP