Signals

Signaling a process and the kill command.

Unix provides a signal mechanism to communicate to a process in memory. You have already sent signals if you have pressed [ctrl]c or [ctrl]z. And bg is a builtin that generates another signal.

Generally, a process may choose to ignore a signal sent to it, allow the default action to occur, or trap the signal and handle in a special way. Some signals can not be trapped or ignored. And we will look at trapping signals when we work with shell scripts.

The primary user command for sending signals is the kill command.

kill is normally used to terminate a background job or a process started from another terminal. However, it can be used to request other changes in the status of a process.

You must be the owner of the process to successfully send a signal.

There are a large number of signals known by a system but only some of these are of use or are used by the user.

Some system help on kill and signal

The most useful user signals are :

Signal
nameSignal
id
Command
equivalent
Description
 
SIGHUP1kill -HUPHang up
SIGINT2[ctrl]cInterrupt
SIGQUIT3[ctrl]\Interrupt (core dump)
SIGKILL9kill -KILLUntrappable, kill (terminate)
SIGTERM15killStandard termination
SIGCONT18bgRestart a paused process.
SIGSTOP19kill -STOPUntrappable, suspend execution
SIGTSTP15[ctrl]zSuspend execution.

The syntax of kill is :

kill [-signal] process_id_list

kill 11735

The option for kill specifies the signal sent to the process. The default is 15 or SIGTERM. You may specify an alternative signal. It is a numeric value, but most versions on kill support a symbolic form of the numeric option.

For example, the signal option to request a hang up is -1 or -SIGHUP or -HUP.

kill -HUP 12354

The numeric value for some signals may vary from system to system depending on the CPU of the system. So it is better to use the symbolic options.

Also, most shells have a builtin version of kill which may behave differently from the external kill program. The bash version of kill may take either a process ID or a job ID. But the external version, /bin/kill, will only accept process IDs.

Lets look at the signals listed above in more detail.

SIGHUP - (-HUP) requests a hangup. It was initially designed to signal a modem to hang up after properly terminating the communication. Many Unix services or daemons respond to a HUP by re-reading their configuration files rather than shutting down. SIGHUP can be trapped and either ignored or handled special.

SIGHUP can be trapped and is used when you want process to close files and o other housekeeping before terminating. Or when you wish the process to re-read its configuration files.

If you have a process that you have lost interaction with such, as a vi session that is in limbo because you lost your network connection while working on it, try using kill -HUP on the vi session once connection is reestablished.

vi keeps a backup of the file being edited. If you terminate it with -HUP, it may be able to write changes in memory before terminating. You can then attempt to recover it with vi -r.

SIGINT - (-INT) is the signal generated by [ctrl]c. The [ctrl]c must be issued from the keyboard and only to a foreground process. The signal can be sent to a background process or even a process running from another terminal. SIGINT can be trapped.

SIGQUIT - (-QUIT) is the signal generated by [ctrl]\. The [ctrl]\ must be issued from the keyboard and only to a foreground process. SIGQUIT is the same as SIGINT, except that if the command being interrupted is a binary (compiled) program, you will get a core dump that can be used for debugging.

SIGKILL - ( -kill or -KILL) is the terminate with prejudice signal. It cannot be trapped and will always succeed (as long as you own the process). Use this on processes that have gotten out of control. But keep in mind, that unlike SIGHUP, SIGKILL immediately terminates the process with no chance for it to perform any type of housekeeping.

SIGTERM - is the default of the standard kill with no options.

SIGCONT - ( -CONT ) restarts a suspended process in the background. It is the similar to bg, except that you can issue it from a different terminal. If the process requires foreground input, it may immediately go back into suspension.

SIGSTOP - ( -STOP ) stops or suspends the specified process. This signal cannot be trapped.

SIGTSTP - ( -TSTP ) stops or suspends the specified process. This is the signal generated by [ctrl]z. This signal can be trapped.

From /usr/include/i386-linux-gnu/bits/signum.h

For our system :

Maximum of 31 user accessible signals

Maximum of 64 signals

#define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill, unblockable (POSIX). */ #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* Broken pipe (POSIX). */ #define SIGALRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */

#( Create the following function get )

get () { read ans; }

#( Run the following commands )

get &
vi bkg &

#( Run sleep in the foreground and use [ctrl]z to suspend it.)

sleep 3000
[ctrl]z

#( Now run another sleep in the background. Then suspend it with kill -STOP. If no other background processes were running, it should be job&nbs;%4. The job and process ids should be displayed and you can confirm the job id. )

sleep 2500 &
kill -STOP %4

#( Now run jobs -l to see the different suspended states.)

What you see.

The read in the get function requires input from standard input, but because it is run in the background, the OS suspends it until it is brought into the foreground.

( Note that you can run a function as a background process. If you do, it gets its own process id and is launched in its own shell space. )

The vi bkg invokes the vi editor. However, the editor uses the curses library to communicate with the display terminal. Since it is in the background, it cannot do so and gets suspended.

The [ctrl]z suspends the currently running foreground process. The command interpreter restarts, becoming the foreground process.

And finally, we started sleep as a background process and used the STOP signal to suspend its execution.

To terminate these, try :

kill -HUP %1 %2 %3 %4

Give it a moment and run

jobs -l

This will probably terminate everything but the vi. To terminate any remaining jobs, invoke kill with the -KILL option and a list of the job ids that did not terminate.

kill -KILL %job-id


Using process ids rather than job ids.

The c-shell and the bash shell support job control. The original version of the Bourne shell does not. And the bash emulation of the Bourne shell does not unless specifically started with job control. The Bourne shell does support background processes but all signal communication is done with process ids.

Everything we have tried with the kill command and the %job-ids could have been done with the process ids.