保留 set -e 里面的设置 ||要么 &&
Keep set -e setting inside || or &&
我有一个简单的脚本,其中的简单功能可能会导致错误。让我们定义这个函数,并把它打碎:
brokenFunction () {
ls "non-existing-folder"
}
如果我们在检测它是否损坏的块中执行此函数,它会很好地工作:
brokenFunction || printf "It is broken\n"
打印"It is broken"
现在,让我们通过在末尾添加正确的命令来使函数更复杂一些:
#!/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 语句之前停止,并显示下一个块 "It is broken".
确实,如果我检查 brokenFunction
的退出状态代码,它是 0。
我尝试将 set -e
添加到脚本的顶部。行为仍然相同,但如果在没有 ||
的情况下调用 brokenFunction
的退出代码现在变为 2
。如果用它调用,状态码仍然是 0
.
有什么方法可以将 set -e
设置保留在使用 ||
调用的函数中吗?
编辑:我刚刚意识到示例中的函数是无用的。我用一个简单的块和一个条件遇到了同样的问题。
#!/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
将 abort
函数绑定到任何引发的错误;
- 损坏的块在子shell中执行有两个原因。首先是将 set -e 设置保留在块内并限制边框效果。其次是在出错时退出此子 shell(
set -e
效果),而不是整个脚本;
trap - ERR
最后重置 trap
绑定,这意味着脚本的以下部分像以前一样执行。
为了测试边框效果,我们可以添加之前不起作用的部分:
#!/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
我有一个简单的脚本,其中的简单功能可能会导致错误。让我们定义这个函数,并把它打碎:
brokenFunction () {
ls "non-existing-folder"
}
如果我们在检测它是否损坏的块中执行此函数,它会很好地工作:
brokenFunction || printf "It is broken\n"
打印"It is broken"
现在,让我们通过在末尾添加正确的命令来使函数更复杂一些:
#!/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 语句之前停止,并显示下一个块 "It is broken".
确实,如果我检查 brokenFunction
的退出状态代码,它是 0。
我尝试将 set -e
添加到脚本的顶部。行为仍然相同,但如果在没有 ||
的情况下调用 brokenFunction
的退出代码现在变为 2
。如果用它调用,状态码仍然是 0
.
有什么方法可以将 set -e
设置保留在使用 ||
调用的函数中吗?
编辑:我刚刚意识到示例中的函数是无用的。我用一个简单的块和一个条件遇到了同样的问题。
#!/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
将abort
函数绑定到任何引发的错误;- 损坏的块在子shell中执行有两个原因。首先是将 set -e 设置保留在块内并限制边框效果。其次是在出错时退出此子 shell(
set -e
效果),而不是整个脚本; trap - ERR
最后重置trap
绑定,这意味着脚本的以下部分像以前一样执行。
为了测试边框效果,我们可以添加之前不起作用的部分:
#!/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