gpt4 book ai didi

error-handling - 保持 set -e 设置在里面 ||或者 &&

转载 作者:行者123 更新时间:2023-12-03 07:58:20 25 4
gpt4 key购买 nike

我有一个简单的脚本,它有一个简单的函数,可能会导致错误。让我们定义这个函数,并将其破坏:

brokenFunction () {
ls "non-existing-folder"
}

如果我们在一个 block 中执行这个函数来检测它是否被破坏,它会很好地工作:
brokenFunction || printf "It is broken\n"

打印“它坏了”

现在,让我们通过在末尾添加一个正确的命令来使函数更复杂一点:
#!/bin/sh

brokenFunction () {
ls "non-existing-folder"
printf "End of function\n"
}

brokenFunction || printf "It is broken\n"

此脚本打印:
$ ./script.sh 
ls: cannot access 'non-existing-folder': No such file or directory
End of function

虽然我希望函数在 printf 语句之前停止,并且下一个 block 显示“它已损坏”。

事实上,如果我检查 brokenFunction 的退出状态代码, 为 0。

我尝试添加 set -e到脚本的顶部。行为仍然相同,但退出代码为 brokenFunction如果在没有 || 的情况下调用现在变成 2 .如果用它调用,状态码仍然是 0 .

有什么办法可以保留 set -e在使用 || 调用的函数内设置?

编辑:我刚刚意识到示例中的函数没用。我在一个简单的 block 和一个条件下遇到了同样的问题。
#!/bin/sh
set -e
{
ls "non-existing-dir"
printf "End of block\n"
} || {
printf "It is broken\n"
}

打印
$ ./script.sh 
ls: cannot access 'non-existing-dir': No such file or directory
End of block

最佳答案

man bash 中所写, set -e在某些情况下被忽略。 || 之前的命令或 &&就是这样一个语境。
trap在这里看起来像是一个可能的解决方案。使用 trap 的最后一个脚本的可行替代方案看起来像这样:

#!/bin/sh
abort () {
printf "It is broken\n"
}
trap 'abort' ERR
(
set -e
false
printf "End of block\n"
)
trap - ERR

这里有几点需要注意:
  • trap 'abort' ERR绑定(bind)abort对任何引发的错误起作用;
  • 损坏的 block 在子外壳中执行有两个原因。首先是将 set -e 设置保留在 block 内并限制边框效果。其次是在出错时退出这个子shell(set -e 效果),而不是整个脚本;
  • trap - ERR最后重置trap绑定(bind),意味着脚本的以下部分像以前一样执行。

  • 为了测试边框效果,我们可以添加之前不工作的部分:
    #!/bin/sh
    abort () {
    printf "It is broken\n"
    }

    trap 'abort' ERR
    (
    set -e
    false
    printf "End of block\n"
    )
    trap - ERR

    {
    false
    printf "End of second block\n"
    } || {
    printf "It is broken too\n"
    }

    打印:
    It is broken
    End of second block

    关于error-handling - 保持 set -e 设置在里面 ||或者 &&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46180753/

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