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

发布于 2024-10-23 13:50:24 字数 169 浏览 5 评论 0原文

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

trap "mycleanup" EXIT

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

There're many exit points in my bash code. I need to do some clean up work on exit, so I used trap to add a callback for exit like this:

trap "mycleanup" EXIT

The problem is there're different exit codes, I need to do corresponding cleanup works. Can I get exit code in mycleanup?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无名指的心愿 2024-10-30 13:50:24

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

以下示例效果很好:

#!/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 脚本并注意此类问题。

The accepted answer is basically correct, I just want to clarify things.

The following example works well:

#!/bin/bash

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

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

But you have to be more careful if doing cleanup inline, without a function. For example this won't work:

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

Instead you have to escape the $rv and $? variables:

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

You might also want to escape $tmpdir, as it will get evaluated when the trap line gets executed and if the tmpdir value changes later that might not give the expected behaviour.

Edit: Use shellcheck to check your bash scripts and be aware of problems like this.

七月上 2024-10-30 13:50:24

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

I think you can use $? to get the exit code.

别忘他 2024-10-30 13:50:24

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

I've found it is better to separate EXIT trap from the trap for other signals

Example trap test script...

umask 77
tmpfile=`tmpfile.$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM

touch $tmpfile
read -r input 

exit 10

The temporary file is cleaned up.
The file exit value of 10 is preserved!
Interrupts result in an exit value of 2

Basically as long as you don't use "exit" in a EXIT trap, it will exit with the original exit value preserved.

ASIDE: Note the quoting in the EXIT trap. That lets me change what file needs to be cleaned up during the scripts lifetime. I often also include a test for the existence of the $tmpfile before trying to remove it, so I don't even need to set it at the start of the script, only before creating it.

恰似旧人归 2024-10-30 13:50:24

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

#!/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
}

The following code works well. You can store the exit code and define the commands that are needed for each exit code in the trap function.

#!/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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文