【问题标题】:How to trap exit code in Bash script如何在 Bash 脚本中捕获退出代码
【发布时间】:2011-07-15 19:09:24
【问题描述】:

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

trap "mycleanup" EXIT

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

【问题讨论】:

  • trap 'foo' EXIT 或 Trap 'foo' CHLD ?

标签: bash signals exit-code bash-trap


【解决方案1】:

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

下面的例子效果很好:

#!/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$? 变量:

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

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

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

【讨论】:

  • 或者你可以使用单引号:trap 'rv=$?; rm -rf $tmpdir;退出 $rv' INT TERM 退出
【解决方案2】:

我想你可以使用$? 来获取退出代码。

【讨论】:

  • @Todd:变量$BASH_COMMAND$BASH_LINENO 有时也会派上用场。
  • @Todd, @bmk :不要忘记执行的 any 命令会更改 $? 的值;例如, myCmdIWantToTest ;回声$? ;我的RC=$? ; ...现在 myRC 是 echo $ 的“真相”? cmd 被调用。如果 myCmdIWantToTest 退出“false”,则该值将丢失。最好节省$?到一个单独命名的 var 是唯一的。使用 exitCode=$?一般来说,您可以轻松地结束继承一些其他 cmd 的 exitCode (或者更有可能来自 sub-shell(script) )。另外,不要忘记可以将测试退出代码作为 if 的一部分;然后 ; ……菲。就像 myCmdIWantToTest ;然后回声起作用了;否则回显失败;菲
【解决方案3】:

我发现最好将 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 之前,我通常还会对其是否存在进行测试,因此我什至不需要在脚本开头设置它,只需在创建它之前进行设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2020-08-12
    • 1970-01-01
    相关资源
    最近更新 更多