Linux命令之trap - 在脚本中处理信号

用途说明

rap是一个shell内建命令,它用来在脚本中指定信号如何处理。比如,按Ctrl+C会使脚本终止执行,实际上系统发送了SIGINT信号给脚本进程,SIGINT信号的默认处理方式就是退出程序。如果要在Ctrl+C不退出程序,那么就得使用trap命令来指定一下SIGINT的处理方式了。trap命令不仅仅处理Linux信号,还能对脚本退出(EXIT)、调试(DEBUG)、错误(ERR)、返回(RETURN)等情况指定处理方式。

常用参数

       trap [-lp] [[arg] sigspec ...]

 

格式:trap "commands" signals

当shell接收到signals指定的信号时,执行commands命令。(The  command arg is to be read and executed when the shell receives signal(s) sigspec. )

 

格式:trap signals

如果没有指定命令部分,那么就将信号处理复原。比如 trap INT 就表明恢复Ctrl+C退出。(If arg is absent (and there is a single sigspec) or -, each specified signal is reset to its  original  disposition  (the value  it  had  upon  entrance  to  the  shell). )

 

格式:trap "" signals

忽略信号signals,可以多个,比如 trap "" INT 表明忽略SIGINT信号,按Ctrl+C也不能使脚本退出。又如 trap "" HUP 表明忽略SIGHUP信号,即网络断开时也不能使脚本退出。(If arg is the null string the signal specified by each sigspec is ignored by the shell and by the commands it invokes. )

 

格式:trap -p

格式:trap -p signal

把当前的trap设置打印出来。(If arg is not present and -p  has  been supplied,  then  the trap commands associated with each sigspec are displayed.  If no arguments are supplied or if only -p is given, trap prints the list of commands associated  with  each  signal.)

 

格式:trap -l

把所有信号打印出来。(The  -l option  causes  the shell to print a list of signal names and their corresponding numbers.  Each sigspec is either a signal name defined in , or a signal number.  Signal names  are  case  insensitive and  the  SIG prefix is optional.) 

 

格式:trap "commands" EXIT

脚本退出时执行commands指定的命令。(If a sigspec is EXIT (0) the command arg is executed on exit from the shell.)

 

格式:trap "commands" DEBUG

在脚本执行时打印调试信息,比如打印将要执行的命令及参数列表。(If a sigspec is DEBUG, the command arg is executed before every  simple  command,  for  command, case  command,  select command, every arithmetic for command, and before the first command executes in a shell function (see SHELL GRAMMAR above).  Refer to the description of the extdebug option to the  shopt builtin  for  details of its effect on the DEBUG trap.)

 

格式:trap "commands" ERR

当命令出错,退出码非0,执行commands指定的命令。(If a sigspec is ERR, the command arg is executed whenever a simple command has a non-zero exit status, subject to the following conditions.  The ERR trap is not executed if the failed command is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a && or ┅Ι│ list, or if the command’s return  value is  being  inverted via !.  These are the same conditions obeyed by the errexit option.)

 

格式:trap "commands" RETURN

当从shell函数返回、或者使用source命令执行另一个脚本文件时,执行commands指定的命令。(If a sigspec is RETURN, the command arg is executed each time a shell function or a script executed with the . or source    builtins  finishes  executing.   Signals  ignored  upon  entry  to the shell cannot be trapped or reset. Trapped signals that are not being ignored are reset to their original values in a child process when it is created.  The return status is false if any sigspec is invalid; otherwise trap returns true.)

-----------------------------------------------我是分割线------------------------------

1. SIGQUIT
POSIX兼容的平台SIGQUIT其控制终端发送到进程,当用户请求的过程中执行核心转储信号。SIGQUIT通常可以ctrl+ \在Linux上,人们还可以使用Ctrl-4虚拟控制台SysRq yek。

2. SIGTERM
SIGTERM的killall命令发送到进程默认的信号它会导致过程的终止,但是SIGKILL信号不同,可以被捕获和解释忽略)过程。因此SIGTERM类似于问一个进程终止可好清理文件和关闭因为这个原因,许多Unix系统关机期间初始化问题SIGTERM所有非必要的断电过程中,等待秒钟,然后发出SIGKILL强行终止仍然存在任何这样的过程

3. SIGINT
符合POSIX平台,信号情报由它的控制终端,当用户希望中断该过程发送到处理的信号通常ctrl-C在某些系统上“删除”字符或“break”键 - 进程的控制终端用户按下中断正在运行的进程的关键SIGINT被发送

4. SIGKILL
符合POSIX平台上,SIGKILL发送到处理的信号以使其立即终止发送到程序SIGKILL使其立即终止在对比SIGTERMSIGINT,这个信号不能被捕获或忽略并且在接收过程中不能执行任何清理在接收到该信号。
----------------------------------------------我是分割线-----------------------------------------------

信号  ( signal ) 机制是 UNIX 系统中最为古老的进程间通信机制,很多条件可以产生一个信号.


信号的产生:

          1,当用户按下某些按键时,产生信号.

          2,硬件异常产生信号:除数为 0 ,无效的存储访问等等.这些情况通常由硬件检测到,将其通知内核,

                然后内核产生适当的信号通知进程,例如,内核对正访问一个无效存储区的进程产生一个 SIGSEGV 信号.

          3,进程用 kill 函数 将信号发送给另一个进程.

          4,用户可用 kill 命令将信号发送给其他进程.


信号类型 - SIGHUP SIGINT  SIGKILL  SIGTERM  SIGCHLD  SIGSTOP

          下面是几种常见的信号:
          SIGHUP :从终端上发出的结束信号.
          SIGINT   :来自键盘的中断信号 ( ctrl + c ) .
          SIGKILL :该信号结束接收信号的进程 .
          SIGTERM:kill 命令发出 的信号.
          SIGCHLD:标识子进程停止或结束的信号.
          SIGSTOP:来自键盘 ( ctrl + z ) 或调试程序的停止执行信号.

信号处理:

          当某信号出现时,将按照下列三种方式中的一种进行处理.

          1,忽略此信号:

                    大多数信号都按照这种方式进行处理,但有两种信号却决不能被忽略.

                    它们是:SIGKILLSIGSTOP . 这两种信号不能被忽略的原因是:它们向

                    超级用户提供了一种终止或停止进程的方法.

          2,执行用户希望的动作:

                    通知内核在某种信号发生时调用一个用户函数,在用户函数中,执行用户希望的处理.

          3,执行系统默认动作:

                    对大多数信号的系统默认动作是终止该进程.


当系统捕捉到某个信号时,可以忽略该信号或是使用指定的处理函数来处理该信号,或者使用系统默认的方式.

信号处理的主要方法有两种,一种是使用简单的 signal 函数另一个是使用信号集函数.

函数:

                    #include < sys/types.h >

                    #include < signal.h >

                    int kill ( pid_t  pai, int signo )

                   int  raise ( int  signo )


kill 的 pid 参数有四种不同情况:

          1, pid  > 0

                    将信号发送给进程 ID 为 pid 的进程.

          2,pid = 0

                    将信号发送给同组的进程.

          3,pid < 0

                    将信号发送给其进程组 ID 等于 pid 绝对值的进程.

          4,pid = -1

                    将信号发送给所有进程.


Alarm信号闹钟  unsigned int alarm

          使用 alarm 函数可以设置一个时间值 ( 闹钟时间 ),当所设置的时间到了时产生 SIGALRM 信号

          如果不能扑捉此信号,则默认动作终止该进程.

          函数: unsigned int alarm  ( unsigned int seconds )

                              经过了指定的 seconds 秒后会产生信号 SIGALRM.

         每个进程只能有一个闹钟时间,如果在调用 alarm 时,以前已为该进程设置过闹钟时间,而且它还没有

          超时,以前等级的闹钟时间则被新值替换.

          如果有以前登记的尚未超时的闹钟时间,而这次 seconds 值是0 ,则表示取消以前的闹钟.


pause 函数  int   pause ( void )

          pause 函数使调用 进程挂起 直至 捕捉 到一个信号 .

          函数: int   pause ( void )

          只有执行了一个信号处理函数后,挂起才结束.


signal 函数  void ( *signal ( int signo  ,   void ( *func ) ( int ) ) ) ( int ):

          #include < signal.h >

          void ( *signal ( int signo  ,   void ( *func ) ( int ) ) ) ( int )

          如何理解:

          typedef  void  ( *sighandler_t ) ( int )

          sighandler_t  signal ( int  signum , sighandler_t  handler )

          Func 可能的值是:

          1,SIG_IGN  :忽略此信号.

          2,SIG_DFL :按照系统默认方式处理.

          3,信号处理函数名:使用该函数处理.


你可能感兴趣的:(计算机OS,linux/unix)