gpt4 book ai didi

bash - 在Bash中使用 'set -e'时如何捕获ERR

转载 作者:行者123 更新时间:2023-12-03 08:45:39 25 4
gpt4 key购买 nike

我有一个简单的脚本:

#!/bin/bash
set -e
trap "echo BOO!" ERR

function func(){
ls /root/
}

func

如果脚本失败,我想捕获ERR(因为在这里b/c,我没有权限查看/root)。但是,使用 set -e时不会被捕获。如果没有 set -e,则会捕获ERR。

根据bash手册页,对于 set -e:

... A trap on ERR, if set, is executed before the shell exits. ...



为什么不执行我的陷阱?从手册页看来应该如此。

最佳答案

chepner's answer是最好的解决方案:如果您希望set -e(与set -o errexit相同)与ERR陷阱结合使用,还可以使用set -o errtrace(与set -E相同)
简而言之:使用set -eE 代替set -e:

#!/bin/bash

set -eE # same as: `set -o errexit -o errtrace`
trap 'echo BOO!' ERR

function func(){
ls /root/
}

# Thanks to -E / -o errtrace, this still triggers the trap,
# even though the failure occurs *inside the function*.
func
一个更复杂的示例 trap示例,该示例以红色显示消息并还显示退出代码: trap 'printf "\e[31m%s: %s\e[m\n" "BOO!" $?' ERR man bash说出有关 set -o errtrace/ set -E的信息:

If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases.


我相信正在发生的事情:
  • 不使用-e:ls命令在函数内部失败,并且由于是函数中的最后一条命令,因此该函数将ls的非零退出代码报告给调用者(即顶级脚本范围)。在此范围内,ERR陷阱有效并被调用(但请注意,除非您从陷阱中显式调用exit,否则执行将继续进行)。
  • 使用-e(但不使用-E):ls命令在您的函数内失败,并且由于set -e生效,因此Bash立即直接从函数作用域中退出-并且由于那里没有ERR陷阱在起作用(因为它不是从父范围继承),则不会调用您的陷阱。

  • 虽然 man页不是正确的,但我同意这种行为并不完全明显-您必须推断出它。

    关于bash - 在Bash中使用 'set -e'时如何捕获ERR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55115967/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com