小智 21
为了确保EXIT
信号处理程序不会被执行两次(这几乎总是不是你想要的),它应该始终设置为在EXIT
信号处理程序本身的定义中被忽略或重置.
对于在程序中为它们定义了多个信号处理程序的信号也是如此.
# reset
trap 'excode=$?; cmd; trap - EXIT; echo $excode' EXIT HUP INT QUIT PIPE TERM
# ignore
trap 'excode=$?; trap "" EXIT; cmd; echo $excode' EXIT HUP INT QUIT PIPE TERM
Run Code Online (Sandbox Code Playgroud)
Bra*_*ley 19
我认为陷阱0在所有情况下都在脚本终止之前执行,因此对于清理功能(如删除临时文件等)非常有用.其他信号可以具有专门的错误处理,但应该终止脚本(即调用exit).
我相信,你所描述的实际上会执行两次cmd.一次是信号(例如SIGTERM),再一次是退出(陷阱0).
我相信这样做的正确方法如下(参见POSIX规范trap
):
trap "rm tmpfile" 0
trap "exit 1" TERM HUP ...
Run Code Online (Sandbox Code Playgroud)
这可确保在脚本完成时删除临时文件,并允许您在信号上设置自定义退出状态.
注意:无论是否遇到信号,都会调用陷阱0.
如果您不关心设置退出状态,则陷阱0就足够了.
shell标准未指定在接收到未捕获的信号时是否执行0上的陷阱.特别是,bash和dash表现不同.由于trap cmd-list 0
没有为任何信号设置陷阱,bash将在收到SIGTERM时执行cmd-list,但dash不会.给定trap cmd-list 0 2
,bash在收到SIGTERM后执行cmd-list一次,dash执行cmd-list两次.