Unix Signals and Traps

Unix - 信号和陷阱

在本章中,我们将详细探讨Unix中的信号和陷阱。

信号是发送到程序的软件中断,指示发生了重要事件。事件可能因用户请求而异,内存访问错误不正确。一些信号,例如中断信号,表示用户已经要求程序做一些不在通常的控制流程中的事情。

下表列出了您可能遇到并希望在程序中使用的常见信号 -

信号名称 信号号码 描述
SIGHUP 1 在控制终端检测到挂断或控制进程死亡
SIGINT 2 如果用户发送中断信号(Ctrl + C)
SIGQUIT 3 如果用户发送退出信号(Ctrl + D),则发出
SIGFPE 8 如果尝试非法数学运算,则发出
SIGKILL 9 如果一个进程获得这个信号,它必须立即退出,不执行任何清理操作
SIGALRM 14 闹钟信号(用于定时器)
SIGTERM 15 软件终止信号(默认情况下由kill发送)

信号列表

有一个简单的方法来列出系统支持的所有信号。只需发出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之间的实际信号列表有所不同。

默认动作

每个信号都有与之相关的默认动作。信号的默认操作是脚本或程序在接收到信号时执行的操作。

一些可能的默认动作是 -

  • 终止进程。

  • 忽略信号。

  • 转储核心 这将创建一个名为core的文件,其中包含当进程收到信号时的内存映像。

  • 停止进程。

  • 继续停止进程。

发送信号

向程序或脚本传递信号有几种方法。最常见的一个是用户在脚本执行时键入CONTROL-CINTERRUPT键

当您按Ctrl + C键时,会将SIGINT发送到脚本,并根据定义的默认操作脚本终止。

传递信号的另一种常见方法是使用kill命令,其语法如下:

$ kill -signal pid

这里的信号是要传递的信号的数量或名称,而pid是信号应发送到的进程ID。例如 -

$ kill -1 1001

上述命令将HUP或挂起信号发送到正在运行进程ID 1001的程序要将kill信号发送到同一个进程,请使用以下命令 -

$ kill -9 1001

这会导致进程ID 1001运行的进程死机

陷阱信号

执行shell程序期间按住Ctrl + C或Break键,通常该程序将立即终止,并且您的命令提示符返回。这可能并不总是令人满意的。例如,您可能会最终留下一堆不会被清理的临时文件。

捕获这些信号是很容易的,trap命令具有以下语法 -

$ trap commands signals

这里命令可以是任何有效的Unix命令,甚至是用户定义的函数,并且信号可以是您想要捕获的任何数量的信号的列表。

shell脚本中的陷阱有两个常见的用途:

  • 清理临时文件
  • 忽略信号

清理临时文件

作为trap命令的示例,以下显示了如何删除某些文件,然后如果有人尝试从终端中止程序,则退出 -

$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2

从shell程序中这个陷阱被执行的那一点,如果程序接收到信号2 ,那么两个文件work1 $$dataout $$将被自动删除。

因此,如果用户在执行此陷阱之后中断程序的执行,则可以放心这两个文件将被清除。rm之后退出命令是必要的,因为没有它,执行将在程序中在接收到信号时停止的时候继续执行。

产生信号号1用于挂机有人故意挂断线或线意外断开连接。

您可以通过将信号号1添加到信号列表中来修改上述陷阱,以便在这种情况下删除两个指定的文件 -

$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2

现在这些文件将被删除,如果该行被挂起或按Ctrl + C键。

指定为trap的命令必须用引号括起来,如果它们包含多个命令。还要注意,shell在执行陷阱命令时也会在接收到列出的信号之一时扫描命令行。

因此,在前面的示例中,在执行陷阱命令时,WORKDIR$$的值将被替换。如果您希望在接收到信号1或2时发生此替换,则可以将命令放在单引号内 -

$ trap \"rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit\" 1 2

忽略信号

如果为trap列出的命令为空,则在接收到指定的信号时将被忽略。例如,命令 -

$ trap \"\" 2

这表明中断信号将被忽略。执行不希望中断的操作时,可能需要忽略某些信号。您可以按如下方式指定要忽略的多个信号 -

$ trap \"\" 1 2 3 15

请注意,必须为要忽略的信号指定第一个参数,并且不等同于写入以下内容,它具有自己的独立意义 -

$ trap  2

如果忽略一个信号,所有的子shell也忽略该信号。但是,如果您指定在接收到信号时采取的操作,则所有子shell在接收到该信号时仍将采取默认操作。

重置陷阱

在更改了接收到信号后要执行的默认操作之后,如果您只是省略第一个参数,则可以使用陷阱重新进行更改。所以 -

$ trap 1 2

这会将接收到信号1或2的操作重置为默认值。

Copyright © 2002-2017 vue5.com 版权所有

Top