UNIX 信号和陷阱
信号发送到一个程序来表示,一个重要的事件已经发生软件中断。事件可以从用户请求访问非法内存错误。一些信号,例如中断信号,表明用户提出的程序来完成的东西,而不是在通常的控制流。
以下是一些你可能会遇到的,要在程序中使用的更常见的信号:
信号名称 | 信号数 | 描述 |
---|---|---|
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). |
信号一览表:
有一个简单的方法,列出了所有你的系统支持的信号。只要发出 kill -l 命令,它会显示所有支持的信号:
$ 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
实际的信号列表之间的Solaris,HP-UX 和 Linux。
默认操作:
每个信号都有默认与它相关联的动作。信号的默认操作是,当它接收信号的动作脚本或程序执行。
有些可能违反的操作是:
-
终止进程。
-
忽略信号。
-
核心转储。这将创建一个文件称为核心记忆形象的过程,当它收到的信号。
-
停止进程。
-
继续停止的进程。
发送信号:
有几种方法提供一个程序或脚本的信号。其中最常见的是执行脚本时用户键入Control-C或INTERRUPT 键。
当你按下Ctrl+ C键发送一个SIGINT的脚本,并按照定义的默认动作脚本终止。
其他常见的传送信号的方法是使用kill命令的语法如下:
$ kill -signal pid
signal 信号提供的电话号码或姓名,pid是信号要发送到的进程ID。示例:
$ kill -1 1001
HUB或挂起信号发送到正在运行的程序的进程ID 1001。发送kill信号相同的过程使用以下命令:
$ kill -9 1001
这会杀死正在运行的进程的进程ID 1001。
捕获信号:
当你按下Ctrl + C键或Break键在终端一个shell程序的执行过程中,正常程序将立即终止,并返回命令提示符。这可能并不总是可取的。例如,你可能最终留下了一堆临时文件,将不会清理。
捕获这些信号是很容易的,trap命令的语法如下:
$ trap commands signals
这里的命令可以是任何有效的Unix命令,或什至一个用户定义的函数,信号可以是任意数量的信号,你想来捕获的列表。
在shell脚本中的陷阱有三种常见的用途:
-
清理临时文件
-
忽略信号
清理临时文件:
trap命令作为一个例子,下面展示了如何可以删除一些文件,然后退出,如果有人试图从终端中止程序:
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
执行shell程序,这个陷阱的角度,这两个文件work1$$ 和 dataout$$ 将被自动删除,如果程序接收信号数为2。
因此,用户中断执行,如果执行的程序后,这个陷阱你可以放心,这两个文件将被清理。 exit 命令如下 rm 是必要的,因为没有它的执行将继续在节目中的一点,它离开时收到信号。
1号信号产生挂断:要么有人故意挂断线路或线路被意外断开。
您可以修改前面的陷阱也删除指定的文件,在这种情况下,两个信号信号1号添加到列表:
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
现在,这些文件将被删除,如果该行被挂了,或者按Ctrl+ C键被按下。
来捕获指定的命令必须用引号括起来,如果它们包含一个以上的命令。另外请注意,在 shell 命令行扫描 trap 命令得到执行,并再次当一个所列出的的信号被接收的时间。
WORKDIR 值 $$ 所以在前面的例子中,将被取代 trap 命令执行的时间。如果你想这种替代发生在收到信号1或2的时间你可以把单引号内的命令:
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
忽略信号:
如果陷阱列出的命令是空的,指定的信号接收时,将被忽略。例如,下面的命令:
$ trap '' 2
指定的中断信号是被忽略的。你可能要忽略某些信号时进行一些操作,不希望打断。可以指定多个信号被忽略如下:
$ trap '' 1 2 3 15
注意,第一个参数必须被指定为一个信号被忽略,而不是相当于写入下面的内容,它具有独立的含义也各有:
$ trap 2
如果你忽略了一个信号,所有的子shell也忽略该信号。不过,如果指定要采取的行动在收到的信号,所有的子shell仍然会在收到该信号的默认操作。
重设陷阱:
当你改变了默认在收到信号后应采取的动作,你可以改变它回来的陷阱,如果你只是省略第一个参数;
$ trap 1 2
复位应采取的动作收到信号1或2 返回默认。