53

我的 bash 代码中有很多退出点。我需要在退出时做一些清理工作,所以我使用陷阱为退出添加回调,如下所示:

trap "mycleanup" EXIT

问题是退出代码不同,我需要做相应的清理工作。我可以在 mycleanup 中获得退出代码吗?

4

4 回答 4

70

接受的答案基本上是正确的,我只是想澄清一下。

以下示例运行良好:

#!/bin/bash

cleanup() {
    rv=$?
    rm -rf "$tmpdir"
    exit $rv
}

tmpdir="$(mktemp)"
trap "cleanup" EXIT
# Do things...

但是,如果在没有函数的情况下进行内联清理,则必须更加小心。例如,这将不起作用:

trap "rv=$?; rm -rf $tmpdir; exit $rv" EXIT

相反,您必须转义$rvand$?变量:

trap "rv=\$?; rm -rf $tmpdir; exit \$rv" EXIT

您可能还想 escape $tmpdir,因为它会在执行陷阱行时进行评估,并且如果tmpdir稍后值发生更改,则可能不会给出预期的行为。

编辑:使用shellcheck检查您的 bash 脚本并注意此类问题。

于 2014-05-13T17:30:27.177 回答
53

我认为您可以使用它$?来获取退出代码。

于 2011-03-15T13:32:56.577 回答
9

我发现最好将 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 之前,我还经常测试它是否存在,所以我什至不需要在脚本的开头设置它,只需要在创建它之前。

于 2017-01-19T00:10:55.683 回答
0

以下代码运行良好。您可以存储退出代码并在陷阱函数中定义每个退出代码所需的命令。

#!/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
}
于 2022-01-20T10:39:40.650 回答