提问人:William Pursell 提问时间:11/14/2011 更新时间:5/10/2017 访问量:24318
是否需要指定 EXIT 以外的陷阱?
Is it necessary to specify traps other than EXIT?
问:
我看到很多 shell 脚本都这样做:
trap cmd 0 1 2 3 13 15 # EXIT HUP INT QUIT PIPE TERM
在我目前可以访问的每个 shell 中,除 0 之外的所有陷阱都是冗余的,如果简单地指定陷阱,则会在收到信号时执行 cmd:
trap cmd 0
后一种规范是否足够,或者某些 shell 是否需要指定其他信号?
答:
我认为在所有情况下,陷阱 0 都是在脚本终止之前执行的,因此对于清理功能(例如删除临时文件等)很有用。其他信号可以有专门的错误处理,但应终止脚本(即调用退出)。
我相信,您所描述的实际上会执行 cmd 两次。一次用于信号(例如 SIGTERM),另一次用于退出(陷阱 0)。
我相信正确的方法是这样做的(参见陷阱
的POSIX规范):
trap "rm tmpfile" 0
trap "exit 1" TERM HUP ...
这可确保在脚本完成时删除临时文件,并允许您在信号上设置自定义退出状态。
注意:无论是否遇到信号,都会调用陷阱 0。
如果您不关心设置退出状态,陷阱 0 就足够了。
评论
0
trap "...cleanup..." 0
ERR
EXIT
shell 标准没有指定在接收到未捕获信号时是否执行 0 上的陷阱。特别是,bash 和 dash 的行为不同。在没有为任何信号设置陷阱的情况下,bash 将在收到 SIGTERM 后执行 cmd-list,但 dash 不会。给定 ,bash 在收到 SIGTERM 时执行一次 cmd-list,而 dash 执行 cmd-list 两次。trap cmd-list 0
trap cmd-list 0 2
评论
trap ... 0
trap "exit 1" SIGTERM ...
为了确保信号处理程序不会被执行两次(这几乎总是不是您想要的),应始终将其设置为在信号处理程序本身的定义中被忽略或重置。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
评论
上一个:惯用的缓冲器os。标准
评论