如何检查Shell陷阱是否被忽略?实现is_trap_exit_set函数
问题解答
核心结论
- Bash 中,子Shell执行
trap -p会显示父Shell的陷阱定义,但这些继承来的陷阱默认不会在子Shell退出时执行。无法直接通过trap -p的输出来判断陷阱是否会被执行,因为它不会区分继承的陷阱和当前Shell主动设置的陷阱。 - 要实现
is_trap_exit_set函数,必须自行跟踪当前Shell中EXIT陷阱的赋值操作——Bash没有提供原生方法区分“仅显示但不执行的继承陷阱”和“会执行的本地陷阱”。
实现方法
通过重写trap内置命令,跟踪当前Shell是否主动设置过EXIT陷阱:
# 全局变量,标记当前Shell是否主动设置过EXIT陷阱 _has_exit_trap=0 # 重写trap命令,跟踪EXIT陷阱的设置操作 trap() { # 仅处理非-p选项的EXIT陷阱设置 if [[ "$1" != "-p" && "$2" == "EXIT" ]]; then _has_exit_trap=1 fi # 调用原生trap命令执行实际操作 builtin trap "$@" } is_trap_exit_set() { # 根据标记返回结果:1为true,0为false return $_has_exit_trap }
验证示例
将上述代码加入用户提供的示例中,执行后会符合预期:
- 最外层子Shell主动设置了EXIT陷阱,
is_trap_exit_set返回true - 第一个内层子Shell仅继承陷阱,未主动设置,
is_trap_exit_set返回false - 第二个内层子Shell通过
eval "$(trap -p EXIT)"主动设置了陷阱,is_trap_exit_set返回true
示例执行输出与用户提供的一致:
923059 exiting 923060 exiting hello from 923060 923058 exiting hello from 923058
内容的提问来源于stack exchange,提问作者KamilCuk
相关产品推荐
相关产品推荐

