如果在程序运行时按下Ctrl+C或Ctrl+\组合键,程序就会在信号到达的那一刻立即终止。
trap命令可以控制程序收到信号后的行为。
信号被定义为由一个整数构成的异步信息,可以由某个进程发给另一个进程,也可以在用户按下某些特定的键或发生某种异常事件时,由操作系统发给某个进程。
trap命令通知shell:
如果收到某个信号,就终止正在执行的命令。
如果trap命令后面跟着括在引号中的命令,则收到指定信号时,shell会执行这个命令串。
shell要把这个命令串读两遍,设置信号陷阱时读一遍,信号到达时再读一遍。
如果命令串两端是双引号,shell会在第一次设置该陷阱时执行该命令串中所有变量替换和命令替换。
如果命令串两端是单引号,则其中的变量替换和命令替换要等到探测到并捕获信号后才进行。
使用kill -l就能得到所有信号的列表。
[root@centos bourne]# 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
trap命令格式:
trap '命令;命令' 信号编号
[root@centos bourne]# trap 'rm tmp*; exit 1' 1 2 15
当信号1(挂起)、信号2(中断,等同于按下Ctrl+C组合键)和信号15(软件终止)中任何一个到达时,删除所有临时文件然后退出。
如果脚本在运行过程中收到中断信号,则可以使用trap命令来选择不同的处理方式:正常处理该信号(默认方式)、忽略该信号或创建一个用以处理信号的可调用函数。
要将信号重置为默认行为,在trap命令后面跟上信号的名称或编号即可;
[root@centos bourne]# trap 'trap 2' 2
把信号2的默认动作设置为:当信号到达时,执行引号中的命令串。用户必须连按两次Ctrl+C组合键才能终止程序。第一个trap用于捕捉信号,第二个trap将该信号的陷阱重新设置为它的默认动作,即终止进程。
如果trap命令后面跟的是一对空引号,其后所列的信号都将被进程忽略。
[root@centos bourne]# trap " " 1 2
信号1和信号2将被shell忽略。
QUIT信号的默认动作是终止进程并生成core文件。
[root@centos 20110522]# more trapping
#!/bin/sh
# Scriptname: trapping
# Script to illustrate the trap command and signals
trap 'echo "Ctrl-C will not terminate $0."' 2
trap 'echo "Ctrl-\ will not terminate $0."' 3
echo "Enter any string after the prompt."
echo "When you are ready to exit, type \"stop\"."
while true
do
echo -n "Go ahead...> "
read reply
if [ "$reply" = stop ]
then
break
fi
done
如果在函数中使用陷阱来处理某个信号,一旦该函数被调用,就会影响到整个脚本对该信号的处理,因为陷阱对脚本而言是全局的。
#!/bin/sh
# Scriptname: FL0857
trapper() {
echo "In trapper"
trap 'echo "Caught in a trap!"' 2
# Once set, this trap affects the entire script. Anytime
# ^C is entered, the script will ignore it.
}
while :
do
echo "In the main script"
trapper
echo "Still in main"
sleep 5
done
陷阱被设置为忽略中断键(Ctrl+C),只有用kill命令终止脚本才能跳出循环结束运行。本例说明在函数中使用陷阱可能会引起潜在的负作用。
键入trap并回车就能列出所有陷阱和指定给它们的命令,例如:
[root@centos bourne]# trap
trap -- ' ' SIGHUP
trap -- ' ' SIGINT
trap -- 'rm tmp*; exit 1' SIGTERM
调试脚本
使用sh命令的-n选项就能对脚本进行语法检查而无需实际运行其中的任何一条命令。如果脚本中存在语法错误,shell会将它显示出来;如果没有错误,shell就不显示任何内容。
最常用的脚本调试手段是用-x选项运行set命令,或把-x选项作为参数传给sh命令。参见下面图片中的调试选项,这些选项使能够跟踪脚本的执行。
使用这些调试选项后,shell对脚本中每条命令的处理过程是:先执行替换,然后显示,最后再执行它。shell显示脚本中的行时,会在行首添上一个加号(+)。
如果打开详细选项,或者在启动Bourne shell时加上-v选项(sh -v 脚本名),脚本中的每一行都会按它在脚本中的原样显示在屏幕上,然后被执行。
阅读(1851) | 评论(0) | 转发(0) |