411 REFERENCE · Wikibooks
Guide to Unix/Explanations/Signals
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Signals
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
PID TTY TIME CMD
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
PID TTY TIME CMD
12203 pts/7 0:01 ksh
[1] + Killed sleep 1000 &
Upon receiving the SIGKILL signal the
sleep process terminates.
Traps
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
PID TTY TIME CMD
12203 pts/7 0:01 bash
[1] + Quit(coredump) sleep 1000 &
$ ls core
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
catch_signal.sh:
#!/bin/bash
trap 'echo "GOTCHA!"' INT KILL
while :
do sleep 10
done
Run catch_signal.sh in background:
$ catch_signal.sh &
[1] 15053
$ kill -INT 15053
$ GOTCHA!
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 catch_signal.sh; in foreground:
$ catch_signal
Hit the interrupt key (control-C usually):
^CGOTCHA!
Now hit the quit key:
^\catch_signal[3]: 15102 Quit(coredump)
$ ls core # will have generated a core file
core
Nohup
Commands run with nohup do not terminate when
the user logs off.
Create the script in the file dont_hangup.sh and
make it executable:
#!/bin/bash
while :
do
date
sleep 100
done
Run it in background preceded by the command nohup:
$ nohup dont_hangup.sh &
[1] 15224
Sending output to nohup.out
Check its running:
id (12203 in this case):
$ ps -fu aholt
aholt 15224 12203 pts/7 sh ./dont_hangup.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 dont_hangup.sh is
still running:
$ ps -fu aholt
aholt 15224 1 ? 0:00 sh ./dont_hangup.sh
aholt 15237 15224 ? 0:00 sleep 100
While "dont_hangup.sh" 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
deep