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 −
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)
# trap -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN
35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4
39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
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.
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 −
$ kill -signal pid
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 −
$ kill -1 1001
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 −
$ kill -9 1001
This kills the process running with process ID 1001.
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 −
$ trap commands signals
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
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
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.
exit是必须的,否则执行完rm命令之后,会继续从接收到信号的地方继续执行脚本。
上面用双引号的时候,变量替换会在执行trap命令的时候进行。
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
这种形式,变量替换会在接收到信号的时候进行。
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 −
$ trap 1 2
or
$ trap - 1 2
[root@dell-per740-64 beaker_analyzer]# trap "echo 111;exit;" EXIT
[root@dell-per740-64 beaker_analyzer]# trap
trap -- 'echo 111;exit;' EXIT
[root@dell-per740-64 beaker_analyzer]# trap -p EXIT
trap -- 'echo 111;exit;' EXIT
cancel beaker job的时候触发了两个信号: 13(SIGPIPE) 和 0(EXIT)
SIGPIPE is a synchronous signal that's sent to a process (thread in POSIX. 1-2004) which attempts to write data to a socket or pipe that has been closed by the reading end.
beaker job abort(local watchdog timeout)的时候也是这两个信号。
beaker job rhts-reboot的时候不触发任何singal
beaker job正常结束会触发EXIT(0)
# 在终端操作的时候
ctrl+c会触发2和0两个信号
关闭terminal时触发1 和 0
在终端rhts-reboot会触发1 和0
EXIT
The exit signal is a bash builtin and can be used to catch any signal.
For all intents and purposes, if you trap exit, it will be executed when the shell process terminates.
Exit the shell, returning a status of n to the shell’s parent.
If n is omitted, the exit status is that of the last command executed.
Any trap on EXIT is executed before the shell terminates.
下面两个命令相同吗?
trap cmd 0 1 2 3 13 15 # EXIT HUP INT QUIT PIPE TERM
trap cmd 0
I think trap 0 is executed just prior to script termination in all cases, so is useful for cleanup functionality (like removing temporary files, etc).
The other signals can have specialized error handling but should terminate the script (that is, call exit).
EXIT会在脚本退出之前执行,并且一定会执行。它适合做cleanup操作。
其他的信号可以做其他的各种工作,但是应该终止脚本(就是 call XIT)
What you have described, I believe, would actually execute cmd twice. Once for the signal (for example SIGTERM) and once more on exit (trap 0).
上面的第一个trap,会导致cmd被执行两次,一次是EXIT,一次是其他signal。
I believe the proper way to do this is like the following (see POSIX specification for trap):
trap "rm tmpfile" 0
trap "exit 1" TERM HUP ...
This ensures a temporary file is removed upon script completion, and lets you set custom exit statuses on signals.
NOTE: trap 0 is called whether a signal is encountered or not.
不管是否遇到信号,都会调用Trap 0
If you are not concerned with setting an exit status, trap 0 would be sufficient.
trap 'delete_netns_link' 0
for signal in 1 2 3 13 14 15; do
trap 'delete_netns_link; trap - $signal; kill -$signal $$' $signal
done
# cat s1.sh
#!/bin/bash
trap "echo s1 trap;" EXIT
echo "This is s1.sh."
source ./s2.sh
# cat s2.sh
#!/bin/bash
trap 'echo s2 trap' EXIT
#trap - EXIT
echo "This is s2.sh"
在s1中通过source掉用s2是在当前进程执行,所以s2中的trap会覆盖s1中的trap
# ./s1.sh
This is s1.sh.
This is s2.sh
s2 trap
# cat s1.sh
#!/bin/bash
trap "echo s1 trap;" EXIT
echo "This is s1.sh."
#source ./s2.sh
./s2.sh
# cat s2.sh
#!/bin/bash
trap 'echo s2 trap' EXIT
#trap - EXIT
echo "This is s2.sh"
在s1中通过./执行s2是在子进程中执行,所以s2中的trap不会覆盖s1中的trap
# ./s1.sh
This is s1.sh.
This is s2.sh
s2 trap
s1 trap