我有一个简单的脚本,它有一个简单的函数,可能会导致错误。让我们定义这个函数,并将其破坏:
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
对任何引发的错误起作用; 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/