我想捕获函数的退出钩子。 Bash 提供了一个很好的信号,称为RETURN
(非 POSIX),当函数返回时会调用该信号,例如
function test_trap() {
trap 'echo trapped' RETURN
sleep 10 # simulate time-consuming commands
echo done
}
当函数返回时我看到“被困”,即使我发送SIGINT
一个Ctrl
C
。 Zsh 有类似的功能吗?我EXIT
在 Zsh 中尝试过,但它只捕获正常返回,而不是当我用 中断时SIGINT
。我也尝试过诱捕两个都 EXIT
并INT
具有相同的钩子函数,但它有两个问题:
- 当我中断它时,钩子表达式会被计算两次。没什么大不了;我的钩子表达式恰好是幂等的。
- Zsh 中的
EXIT
是本地的:从函数返回时,恢复原来的钩子。这类似于局部变量隐藏全局变量的方式。不幸的是,该INT
钩子始终是全局的,因此我指定的任何钩子都会覆盖全局钩子。我需要记住原来的INT
钩子,并在以后恢复它。正确地做到这一点非常棘手;我可能会尝试一下这个。
答案1
这就像函数外部的 EXIT 陷阱一样。退出和被杀是两件事。
因此,就像在函数之外一样,您需要单独处理它们:
test_trap() {
set -o localoptions -o localtraps
trap 'echo "I am exiting."' EXIT
trap 'echo "I have been interrupted, so"; return 1' INT
echo start
sleep 10
echo end
}
test_trap
echo "returned with: $?"
这使:
$ zsh ./that-script
start
^CI have been interrupted, so
I am exiting.
returned with: 1
如果你想要壳(不仅仅是函数)在执行函数时收到处理 SIGINT 信号时退出,替换return 1
为exit
(或者在恢复默认处理程序(trap - INT; kill -s INT "$$"
)后用 SIGINT 杀死自己,如果你想通过信号向你的父母报告你的死亡) 。