如何在Bash脚本中捕获退出代码

时间:2011-03-15 13:15:50

标签: bash signals exit-code bash-trap

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

trap "mycleanup" EXIT

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

3 个答案:

答案 0 :(得分:43)

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

答案 1 :(得分:42)

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

以下示例效果很好:

#!/bin/bash

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

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

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

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

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

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

您可能还想要转义$tmpdir,因为它会在陷阱行执行时进行评估,并且tmpdir值稍后会更改,但不会给您预期的行为。

编辑:使用shellcheck检查您的bash脚本,并注意这样的问题。

答案 2 :(得分:4)

我发现最好将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”,它就会退出并保留原始退出值。

ASIDE:注意EXIT陷阱中的引用。这让我可以在脚本生命周期内更改需要清理的文件。我经常还包含对$ tmpfile varables存在的测试,所以我甚至不需要在脚本的开头设置它。