个性化阅读
专注于IT技术分析

Unix和Linux信号捕获处理介绍及其相关操作教程

点击下载

上一章Unix和Linux教程请查看:Unix和Linux系统日志使用和操作

在本章中我们将详细讨论Unix中的信号捕获和处理。信号是软件中断发送到一个程序,以表明一个重要的事件已经发生。从用户请求到非法内存访问错误,这些事件可能各不相同。

一些信号例如中断信号,表明用户要求程序做一些不属于通常控制流的事情。下表列出了你可能遇到并希望在程序中使用的常见信号:

信号名 信号编号 描述
SIGHUP 1 控制终端检测到挂起或控制进程的销毁
SIGINT 2 如果用户发送中断信号(Ctrl + C)则触发
SIGQUIT 3 当用户发送退出信号时发出(Ctrl + D)
SIGFPE 8 如果试图进行非法数学运算则发出
SIGKILL 9 如果进程收到此信号,它必须立即退出,并且不会执行任何清理操作
SIGALRM 14 闹钟信号(用于定时器)
SIGTERM 15 软件终止信号(默认通过kill发送)

1、列出所有信号

有一种简单的方法可以列出系统支持的所有信号,只需执行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

2、默认动作

每个信号都有一个与之相关联的默认动作,信号的默认操作是脚本或程序在接收到信号时执行的操作,一些可能的默认操作是:

  • 终止过程。
  • 忽略这个信号。
  • 核心转储。这将创建一个名为core的文件,其中包含进程接收到信号时的内存映像。
  • 停止这一进程。
  • 继续停止的进程。

3、发送信号

有几种方法可以将信号传递给程序或脚本,最常见的一种是用户在执行脚本时键入CONTROL-C或中断键。

当你按下Ctrl+C键时,将向脚本发送一个SIGINT,并根据定义的默认操作脚本终止。传递信号的另一种常用方法是使用kill命令其语法如下:

$ kill -signal pid

这里的信号是要发送的信号的编号或名称,pid是应该发送信号的进程ID如:

$ kill -1 2020

上面的命令将HUP或挂起信号发送给正在使用进程ID 1001运行的程序。若要向同一进程发送终止信号,请使用以下命令:

$ kill -9 2021

4、捕获信号

当你在shell程序执行过程中按下Ctrl+C或中断键时,通常该程序会立即终止,并返回命令提示符。这可能并不总是可取的,例如你可能会留下一堆无法清理的临时文件。

捕获这些信号非常容易,trap命令具有以下语法:

$ trap commands signals

这里的命令可以是任何有效的Unix命令,甚至可以是用户定义的函数,而signal可以是你希望捕获的任意数量的信号的列表。

在shell脚本中有两种常见的trap用法:

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

5、清理临时文件

作为trap命令的一个示例,下面展示了如何删除一些文件,然后在有人试图从终端中止程序时退出:

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

在shell程序中执行这个陷阱时,如果程序接收到信号2,work1$$和dataout$$这两个文件将被自动删除。

因此如果用户在执行此陷阱之后中断程序的执行,你可以确信这两个文件将被清除。在rm之后的exit命令是必需的,因为如果没有它,程序中的执行将在接收到信号时停止。

1号信号用于挂起。要么是有人故意挂断电话,要么是线路意外断开。你可以修改前面的trap,通过将信号1添加到信号列表中来删除两个指定的文件:

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

6、忽略信号

如果为trap列出的命令为null,则在接收时将忽略指定的信号,例如下命令:

$ trap '' 2

这指定中断信号将被忽略。在执行不想被中断的操作时,你可能希望忽略某些信号,你可以指定多个要忽略的信号如下:

$ trap '' 1 2 3 15

请注意必须指定第一个参数才能忽略信号,并且不等于编写下面的内容,因为它有自己的独立含义:

$ trap  2

如果你忽略一个信号,所有的子shell也会忽略这个信号。但是如果你指定在接收到信号时要采取的操作,那么所有子shell在接收到信号时仍将采取默认操作。

7、重置trap

在你更改了接收到信号时要采取的默认操作之后,如果你只是忽略了第一个参数,那么你可以使用trap再次更改它:

$ trap 1 2

这将在收到信号1或2时采取的操作重置为默认操作。

赞(0)
未经允许不得转载:srcmini » Unix和Linux信号捕获处理介绍及其相关操作教程

评论 抢沙发

评论前必须登录!