Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

If I have a series of nested functions, how can I break out of all of them from the innermost function?

EDIT: Busy looking into the builtin 'trap'...

share|improve this question
    
Functions can't be nested in shell. There are no closures. Did you mean break out of all but the outermost scope? Innermost doesn't make sense. –  ormaaj Mar 6 '13 at 16:48
    
@ormaaj: All of them from the innermost function. –  Dennis Mar 6 '13 at 16:50
    
Ahh ok, gotcha. –  ormaaj Mar 6 '13 at 16:54
add comment

3 Answers

A rather ugly but easy way to achieve this would be defining STOP variable and checking it after every function call:

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

Not pretty, but it works in bash and zsh.

share|improve this answer
add comment

Here's a not-necessarily-portable hack that jumps out of all the required levels bypassing all RETURN traps, effectively prevents returning anything but 0, and is possibly a bug in at least some respects. This particular implementation is Bash-only but can be adapted to other shells.

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}"

output

Current level: 0
Current level: 1
Current level: 2
Current level: 3
Current level: 4
Current level: 5
Returning from level: 0
share|improve this answer
add comment

I went with storing all the logic in a separate shell script instead of using functions. Exit will break out of the script entirely and allow your wrapper script to continue execution.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.