Dag*_*ang 42 bash signals exit-code bash-trap
我的bash代码中有很多退出点.我需要在退出时做一些清理工作,所以我使用trap为这样的退出添加一个回调:
trap "mycleanup" EXIT
Run Code Online (Sandbox Code Playgroud)
问题是有不同的退出代码,我需要做相应的清理工作.我可以在mycleanup中获得退出代码吗?
Pau*_*ias 48
接受的答案基本上是正确的,我只想澄清一些事情.
以下示例运行良好:
#!/bin/bash
cleanup() {
rv=$?
rm -rf "$tmpdir"
exit $rv
}
tmpdir="$(mktemp)"
trap "cleanup" INT TERM EXIT
# Do things...
Run Code Online (Sandbox Code Playgroud)
但是如果在没有函数的情况下进行内联清理,你必须更加小心.例如,这不起作用:
trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT
Run Code Online (Sandbox Code Playgroud)
相反,你必须转义$rv和$?变量:
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT
Run Code Online (Sandbox Code Playgroud)
您可能还想要转义$tmpdir,因为它将在陷阱行执行时得到评估,如果tmpdir值稍后更改,则不会给出预期的行为.
编辑:使用shellcheck检查bash脚本并注意这样的问题.
bmk*_*bmk 47
我想你可以$?用来获取退出代码.
我发现最好将EXIT陷阱与其他信号分开
陷阱测试脚本示例...
umask 77
tmpfile=`tmpfile.$$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM
touch $tmpfile
read -r input
exit 10
Run Code Online (Sandbox Code Playgroud)
临时文件被清理。保留文件出口值10!中断导致退出值为2
基本上,只要您不在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 3 ]]; then
# command 3
fi
}
Run Code Online (Sandbox Code Playgroud)