收到信号后,我可以使用trap
执行一些命令。例如:
trap 'echo hello world' 1 2
如果收到任何指定的信号,则显示“hello world”。
但是如何打印/识别收到的信号名称?
答案 0 :(得分:39)
(如果您只有信号编号并想要名称,kill -l $SIGNAL_NUM
会打印信号的名称;您可以通过在{{1}的调用中使用信号名称而不是数字来避免这种情况如下所示。)
This answer说,识别你在bash中捕获的信号的唯一方法是为你想捕获的每个不同信号写一个单独的包装器。 Another answer on that same question提供了一个包装函数来为您完成:
代码:
trap
如果我运行它,那么我可以向进程发送信号,我得到输出
#!/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.
答案 1 :(得分:7)
在陷阱内(当通过信号触发时),$?变量最初设置为信号编号加128,因此您可以通过将陷阱操作的第一个语句设置为类似
来将信号编号分配给变量。sig=$(($? - 128))
然后,您可以使用kill命令
获取信号的名称kill -l $sig
答案 2 :(得分:2)
一种简单的方法:
_handler() {
signal=$1
echo signal was $signal
}
trap '_handler SIGTERM' SIGTERM
trap '_handler SIGINT' SIGINT
答案 3 :(得分:1)
请参考上面的$?
解决方案:$?
将反映最后执行的命令的退出代码。考虑一下:
#!/bin/bash
trap 'echo CODE: $?; exit 1' 1 2 3 15
sleep 3600
如果运行此命令并按 Ctrl-C ,它将打印CODE: 130
。这是因为sleep
可执行文件被SIGINT中断并以该代码退出。
将其与以下内容进行比较:
#!/bin/bash
trap 'echo CODE: $?; exit 1' 1 2 3 15
read X
如果运行此命令并按 Ctrl-C ,它将打印CODE: 0
,可能是因为read
命令是内置命令,退出代码规则不同(发生同样的情况)如果您要打断while : ; do : ; done
)。
因此,$?
仅在中断外部命令时告诉您有关信号的信息,而和仅在特定程序没有捕获到信号并以其自己的退出代码退出时才告诉您。以防万一是上面的bash脚本:收到SIGINT时,它将以代码1
而不是130
退出。
答案 4 :(得分:0)
for s in {1..64} ;do trap "echo trap $s" $s ;done
或者没有bash-isms
s=1 ;while [ $s -le 64 ] ;do trap "echo trap $s" $s ;s=$((s+1)) ;done
设置64个单独的陷阱,每个可能的信号一个。