我有以下脚本:
#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat # wait indefinitely
当我发送SIGHUP
(使用kill -HUP pid
)时,没有任何反应。
如果我稍微改变一下脚本:
#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT # add this
trap "echo HUP" SIGHUP
cat # wait indefinitely
...然后脚本echo HUP
在退出时正确执行操作(当我按 Ctrl+C 时):
roger@roger-pc:~ $ ./hupper.sh
We are 6233
^CHUP
这是怎么回事?我应该如何SIGHUP
向该脚本发送信号(不一定是)?
答案1
答案2
@xhienne 已经解释了原因,但是如果您想让信号立即起作用(而不是退出脚本),您可以将代码更改为:
#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP
{ cat <&3 3<&- & pid=$!; } 3<&0
while
wait "$pid"
ret=$?
"$interrupted"
do
interrupted=false
done
exit "$ret"
文件描述符的小技巧是解决bash
将 stdin 重定向到/dev/null
后台启动的命令这一事实。
答案3
我注意到,当 EXIT 上有陷阱时,脚本在收到信号时不会等待外部命令结束。示例脚本:
$ cat test-trap
#!/bin/bash
echo "We are $$"
trap "echo 'Trapping EXIT'" EXIT
cat
运行它:
$ ./test-trap
We are 24814
向其发送 SIGHUP:
$ ./test-trap
We are 24814
# Doing `kill -HUP 24814` in another terminal
Trapping EXIT
Hangup
不过,可能有一只困惑的被遗弃的猫:
cat: -: Input/output error
为了解决这个问题,您可能需要从陷阱调用的函数中搜索并终止子进程。
按Ctrl+ C:
$ ./test-trap
We are 24814
^CTrapping EXIT
现在,当您按Ctrl+D而不是Ctrl+时C,cat 命令会正常结束。但是当脚本结束时陷阱就会被执行:
$ ./test-trap
We are 40183
# I pressed Ctrl+D here...
Trapping EXIT
您可以通过取消脚本末尾的陷阱来防止这种情况:
#!/bin/bash
echo "We are $$"
trap "echo 'Trapping EXIT'" EXIT
cat
trap - EXIT
我无法找到有关捕获 EXIT 的这种不同行为的任何文档。也许其他人可以?