2012-02-13 44 views

回答

35

(如果你只有一个信号的数量和所需的名称,kill -l $SIGNAL_NUM打印信号的名称,那么就可以避免通过使用您的来电trap如下信号名称,而不是数字。)

This answer表示识别您在bash中捕获哪个信号的唯一方法是为要陷入的每个不同信号编写一个单独的包装。 Another answer on that same question提供了一个包装函数来为你做它:

代码:

#!/bin/bash 

trap_with_arg() { 
    func="$1" ; shift 
    for sig ; do 
     trap "$func $sig" "$sig" 
    done 
} 

func_trap() { 
    echo Trapped: $1 
} 

trap_with_arg func_trap INT TERM EXIT 

read # Wait so the script doesn't exit. 

如果我运行的,那么我就可以将信号发送到过程,我得到的输出喜欢

Trapped: INT 
Trapped: TERM 
Trapped: EXIT 
+0

感谢。但它不会为我工作。该函数trap_with_arg()将阻塞,直到收到信号。我希望在收到信号时显示信号名称 - 脚本正在执行。就我而言,我不是在等待信号。每当它到达时,都需要打印。 – 2012-02-13 07:23:01

+8

'trap_with_arg()'不会阻塞。它遍历其输入,设置陷阱处理程序,然后返回。 – perelman 2012-02-13 07:34:37

+0

Lunar Mushrooms,它可能会阻止,因为脚本中的命令正在运行时未处理陷阱。如果您在处于“睡眠”中间时发出了脚本信号,则在“睡眠”完成之前它不会执行您的陷阱。它不是异步的。陷阱将捕获脚本中命令之间的信号。 – Ray 2015-04-04 01:13:08

6

在陷阱(当通过信号触发时),$?变量最初设置为信号数加128,这样你就可以通过使疏水阀动作的第一个语句类似

sig=$(($? - 128)) 

分配信号到变量,然后可以使用得到信号的名称kill命令

kill -l $sig 
+1

这本来不错,但在Linux 3.10上对Bash 4.3.30不起作用:在信号处理程序开始时'$?'为0,即使它已被'TERM'信号调用。 – 2016-03-24 09:04:43

+0

这似乎是最好的答案,因为它更直接。 – codeforester 2017-11-26 02:51:43

1

一个简单的方法来做到这一点:

_handler() { 
    signal=$1 
    echo signal was $signal 
} 

trap '_handler SIGTERM' SIGTERM 
trap '_handler SIGINT' SIGINT