我有以下脚本:
#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat # wait indefinitely
Run Code Online (Sandbox Code Playgroud)
当我发送SIGHUP
(使用kill -HUP pid
)时,没有任何反应。
如果我稍微更改脚本:
#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT # add this
trap "echo HUP" SIGHUP
cat # wait indefinitely
Run Code Online (Sandbox Code Playgroud)
...然后脚本在echo HUP
退出时做正确的事情(当我按 Ctrl+C 时):
roger@roger-pc:~ $ ./hupper.sh
We are 6233
^CHUP
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?我应该如何SIGHUP
向此脚本发送信号(不一定必须是)?
xhi*_*nne 23
Bash 手册指出:
如果 bash 正在等待命令完成并接收到设置了陷阱的信号,则在命令完成之前不会执行陷阱。
这意味着尽管bash
在您发送信号时收到了信号,但只有在以下情况下才会调用 SIGHUP 上的陷阱cat
结束。
如果这种行为是不可取的,那么要么使用bash
内置函数(例如,在循环中使用read
+printf
而不是cat
),要么使用后台作业(请参阅Stéphane 的回答)。
@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"
Run Code Online (Sandbox Code Playgroud)
文件描述符的小动作是解决bash
将 stdin 重定向到/dev/null
后台启动的命令这一事实。