我可以为陷阱处理程序中的 shell 脚本分配不同的退出状态吗?
通过反复试验,我发现调用exit
退出trap
状态是可以改变的。普通命令,无论失败还是成功,都不会改变退出状态。
现在我想知道,我是否可以依赖这种行为,或者这是一些实现怪癖?
我一直试图找到一些关于此的文档,但无济于事。
测试脚本:
#!/bin/bash
function handler {
# a successful command won't change script exit status
echo handler, status=$1
# badcommand won't change script exit status
#badcommand
# exit will change script exit status
#exit 23
}
trap 'handler $?' EXIT
#badcommand
用法:
./trap_test.sh; echo status_out=$?
答案1
我发现[通过]调用
exit
trap 可以改变退出状态。普通命令,无论失败还是成功,都不会改变退出状态。现在我想知道,我是否可以依赖这种行为,或者这是一些实现怪癖?
是的,您可以依赖它,并且它已记录在 shell 中标准:
名称
exit
- 导致 shell 退出
...
描述
...
陷阱EXIT
应在 shell 终止之前执行,除非exit
在该陷阱本身中调用该实用程序,在这种情况下 shell 应立即退出。
...
退出状态如果指定,
退出状态应为,但如果不是无符号十进制整数或大于 ,则n
行为未指定。否则,该值应为最后执行的命令的退出值,如果没有执行命令则为零。n
255
当exit
在陷阱操作中执行时,最后一个命令被认为是紧接在陷阱操作之前执行的命令。
(同样的事情return
)
当没有exit
命令但exit
设置了陷阱时,应应用以下内容:
除非另有说明,命令的退出状态应为该命令执行的最后一个简单命令的退出状态。
以及关于复合命令、顺序列表等的所有规则,这些规则对于EXIT
陷阱的存在没有特殊的例外。
答案2
我没有看到手册页提到它,所以除了查看代码之外,实验似乎是弄清楚会发生什么的最好方法。
对我来说,退出陷阱并不总是改变退出状态是有意义的:脚本可能希望在退出时通过陷阱进行一些清理,但不会让清理扰乱主脚本设置的退出状态。而且,正如您所说,陷阱可以exit
再次运行以设置所需的值。
例如,如果你有这个:
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT
# something
exit 1
可能rm
会将退出状态重置为零,这似乎没什么用。