【Bash百宝箱】shell内建命令之trap

在shell中,内建(builtin)命令trap,格式如下:

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

trap命令用于跟踪Linux信号,当shell收到信号sigspec时,就会读取命令arg并执行它。

首先,看一下Linux有哪些信号。

$ trap -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    

Linux信号以关键字“SIG”开头,每个信号都对应于唯一的数字,下面是这些信号的具体含义。

       Signal     Value     Action   Comment
       ──────────────────────────────────────────────────────────────────────
       SIGHUP        1       Term    Hangup detected on controlling terminal
                                     or death of controlling process
       SIGINT        2       Term    Interrupt from keyboard
       SIGQUIT       3       Core    Quit from keyboard
       SIGILL        4       Core    Illegal Instruction
       SIGABRT       6       Core    Abort signal from abort(3)
       SIGFPE        8       Core    Floating point exception
       SIGKILL       9       Term    Kill signal
       SIGSEGV      11       Core    Invalid memory reference
       SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                     readers
       SIGALRM      14       Term    Timer signal from alarm(2)
       SIGTERM      15       Term    Termination signal
       SIGUSR1   30,10,16    Term    User-defined signal 1
       SIGUSR2   31,12,17    Term    User-defined signal 2
       SIGCHLD   20,17,18    Ign     Child stopped or terminated
       SIGCONT   19,18,25    Cont    Continue if stopped
       SIGSTOP   17,19,23    Stop    Stop process
       SIGTSTP   18,20,24    Stop    Stop typed at terminal
       SIGTTIN   21,21,26    Stop    Terminal input for background process
       SIGTTOU   22,22,27    Stop    Terminal output for background process
       SIGBUS      10,7,10     Core    Bus error (bad memory access)
       SIGPOLL                 Term    Pollable event (Sys V).
                                       Synonym for SIGIO
       SIGPROF     27,27,29    Term    Profiling timer expired
       SIGSYS      12,31,12    Core    Bad argument to routine (SVr4)
       SIGTRAP        5        Core    Trace/breakpoint trap
       SIGURG      16,23,21    Ign     Urgent condition on socket (4.2BSD)
       SIGVTALRM   26,26,28    Term    Virtual alarm clock (4.2BSD)
       SIGXCPU     24,24,30    Core    CPU time limit exceeded (4.2BSD)

       SIGXFSZ     25,25,31    Core    File size limit exceeded (4.2BSD)
       SIGIOT         6        Core    IOT trap. A synonym for SIGABRT
       SIGEMT       7,-,7      Term
       SIGSTKFLT    -,16,-     Term    Stack fault on coprocessor (unused)
       SIGIO       23,29,22    Term    I/O now possible (4.2BSD)
       SIGCLD       -,-,18     Ign     A synonym for SIGCHLD
       SIGPWR      29,30,19    Term    Power failure (System V)
       SIGINFO      29,-,-             A synonym for SIGPWR
       SIGLOST      -,-,-      Term    File lock lost (unused)
       SIGWINCH    28,28,20    Ign     Window resize signal (4.3BSD, Sun)
       SIGUNUSED    -,31,-     Core    Synonymous with SIGSYS

另外,关键字“SIGRT”开头的表示实时Real-time信号,最小值为SIGRTMIN,最大值为SIGRTMAX。

查看当前信号trap状态,使用“-p”选项:

$ trap -p
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
$ trap -p SIGTSTP
trap -- '' SIGTSTP

在trap命令中,对于信号sigspec,如果命令arg未指定或者为“-”,信号trap状态被重置为shell初始状态,如果命令arg为空字符串,信号被忽略。信号sigspec可以是数字,也可以是字符串,不区分大小写,字符串前缀“SIG”可有可无。

sigspec有几个特殊的值。如果为”EXIT“或者数字0,退出shell时执行命令arg。如果为DEBUG,在某些命令执行前先执行命令arg,这些命令包括:单一shell命令、for命令、case命令、select命令、shell函数中的第一个命令。如果为”RETURN“,使用source命令或句点命令执行shell脚本时,会执行命令arg。如果为”ERR“,则任何管道命令、命令列表、组合命令退出状态非0时就执行命令arg,但下列情况例外:while或until关键字后面的命令、if条件测试命令、“&&”或“||”之前的命令、管道命令队列中前面的命令、使用了“!”对命令结果取反的情形。

在进入shell时已经忽略的信号不能进行trap和reset,已trap的信号在进入子shell时会重置为初始状态。trap命令中,信号sigspec无效时返回2即false,其它情况返回0即true。

shell脚本是自上而下执行的,trap命令对其前面的命令没有影响。

下面举例说明trap命令的用法。

例一(EXIT、RETURN、DEBUG):

$ cat foo 
#!/bin/bash

foo_exit()
{
    echo "will exit"
}

foo_return()
{
    echo "will return"
}

foo_debug()
{
    echo "debug..."
}

trap foo_exit EXIT
trap foo_return RETURN
trap foo_debug DEBUG

foo_test()
{
    echo "foo_test called"
}

echo "begin"
foo_test
echo "end"
$ bash foo 
debug...
begin
debug...
foo_test called
debug...
end
debug...
will exit
$ source foo 
debug...
begin
debug...
foo_test called
debug...
end
debug...
will return
$ foo_test 
debug...
foo_test called

例二(SIGINT,Ctrl+C中断sleep):

$ cat foo
#!/bin/bash

foo_signal()
{
    echo "foo_signal"
}

trap foo_signal SIGINT

echo "begin"
sleep 10
echo "end"
$ bash foo
begin
^Cfoo_signal
end
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值