如果我有一系列嵌套函数,如何从最内层的函数中脱离出所有函数?
编辑:忙于研究内置的“陷阱”......
答案1
实现此目的的一种相当丑陋但简单的方法是定义 STOP 变量并在每次函数调用后检查它:
a ()
{
echo a
b; [[ "$STOP" == 1 ]] && return
a; [[ "$STOP" == 1 ]] && return
}
b ()
{
echo b
c; [[ "$STOP" == 1 ]] && return
b; [[ "$STOP" == 1 ]] && return
}
c ()
{
echo c
STOP=1; return
}
a
echo d
虽然不太漂亮,但它在 bash 和 zsh 中可以运行。
答案2
这是一个不一定可移植的 hack,它跳过所有必需的级别,绕过所有RETURN
陷阱,有效地防止返回除 0 之外的任何内容,并且至少在某些方面可能是一个错误。此特定实现仅适用于 Bash,但可以适用于其他 shell。
function f {
printf 'Current level: %d\n' ${n:+"$1"}
if [[ $FUNCNAME != "${FUNCNAME[1]}" ]]; then
[[ $1 == +([[:digit:]]) ]] || return 1
typeset n=$1
while ! f 1; do :; done
unset -v n
elif (( n - $1 )); then
f $(($1 + 1))
else
trap 'printf "Returning from level: %d\n" ${n+"$1"}' RETURN
# return # toggle
break
fi
}
f "${1:-5}"
输出
Current level: 0
Current level: 1
Current level: 2
Current level: 3
Current level: 4
Current level: 5
Returning from level: 0
答案3
当然,它可以以“经典”(类似 C 的错误处理)方式完成,即:
- 从带有状态代码的函数返回。
- 每次函数调用后检查状态代码并执行相应操作。
如果我们只需要非零状态代码(又名错误),
我们可以使用|| command
而不是if [ $? != 0 ]; then command; fi
使其简短而干净:
f1(){
f2(){
if [ "${things_went_wrong}" == y ]; then echo "Sorry!"; return 1; fi
}
f2 some arguments || return 1
}
f1 some arguments || return 1
希望有所帮助。
答案4
我选择将所有逻辑存储在单独的 shell 脚本中,而不是使用函数。Exit 将完全脱离脚本并允许包装器脚本继续执行。