我的 bash 代码中有很多退出点。我需要在退出时做一些清理工作,所以我使用陷阱为退出添加回调,如下所示:
trap "mycleanup" EXIT
问题是退出代码不同,我需要做相应的清理工作。我可以在 mycleanup 中获得退出代码吗?
接受的答案基本上是正确的,我只是想澄清一下。
以下示例运行良好:
#!/bin/bash
cleanup() {
rv=$?
rm -rf "$tmpdir"
exit $rv
}
tmpdir="$(mktemp)"
trap "cleanup" EXIT
# Do things...
但是,如果在没有函数的情况下进行内联清理,则必须更加小心。例如,这将不起作用:
trap "rv=$?; rm -rf $tmpdir; exit $rv" EXIT
相反,您必须转义$rv
and$?
变量:
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" EXIT
您可能还想 escape $tmpdir
,因为它会在执行陷阱行时进行评估,并且如果tmpdir
稍后值发生更改,则可能不会给出预期的行为。
编辑:使用shellcheck检查您的 bash 脚本并注意此类问题。
我认为您可以使用它$?
来获取退出代码。
我发现最好将 EXIT 陷阱与其他信号的陷阱分开
示例陷阱测试脚本...
umask 77
tmpfile=`tmpfile.$$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM
touch $tmpfile
read -r input
exit 10
临时文件被清理。文件退出值 10 被保留!中断导致退出值为 2
基本上只要您不在 EXIT 陷阱中使用“exit”,它就会在保留原始退出值的情况下退出。
旁白:注意 EXIT 陷阱中的引用。这让我可以更改脚本生命周期内需要清理的文件。在尝试删除 $tmpfile 之前,我还经常测试它是否存在,所以我什至不需要在脚本的开头设置它,只需要在创建它之前。
以下代码运行良好。您可以存储退出代码并在陷阱函数中定义每个退出代码所需的命令。
#!/bin/bash
trap cleanup EXIT
cleanup() {
exit_code=$?
if [[ ${exit_code} -eq 1 ]]; then
# command 1
elif [[ ${exit_code} -eq 2 ]]; then
# command 2
elif [[ ${exit_code} -eq 2 ]]; then
# command 2
fi
}