set -e
使用内部函数1不是一个好主意,因为它会导致 shell 因错误而终止。
因此,在 shell 函数中很多我的代码如下所示:
[[ -e $file ]] || {
printf -- 'foo: %s does not exist\n' $file >&2
return -1
}
...这不仅笨重,而且在超出funcstack
.如果有一个error
函数至少可以将上面的代码压缩为这样的代码,那就太好了
[[ -e $file ]] || error -1 '%s does not exist' $file
编写这样的错误函数以供使用解释的脚本(相对于函数)并不太困难:
error () {
local exitstatus=$1
shift
{
printf -- '%s: ' "${funcstack[2]}"
printf -- "$@"
printf -- '\n'
} >&2
exit $exitstatus
}
...但是从其他函数内部调用这个函数是一个坏主意,出于同样的原因,set -e
在函数内部也是一个坏主意。
实现所需功能所需的error
是一种将控制权返回到调用 shell 的“顶层”的方法(从而清除funcstack
,在调用时可能是任意长的error
)。
有没有办法做到这一点?
PS:当然,我确实尝试过这种天真的方法:
error () {
local exitstatus=$1
shift
{
printf -- '%s: ' "${funcstack[2]}"
printf -- "$@"
printf -- '\n'
} >&2
funcstack=()
}
...但是(毫不奇怪),zsh
不会有这些:
error:10: read-only variable: funcstack
1在这篇文章中,我将使用“来自函数内”之类的表达式作为“来自用于交互式使用的 shell 函数内或来自用于获取源的脚本内”的简写。