Wyłamać zagnieżdżone funkcje w powłoce


0

Jeśli mam szereg zagnieżdżonych funkcji, jak mogę wyrwać się z nich wszystkich z najbardziej wewnętrznej funkcji?

EDYCJA: Zajęty, patrząc na wbudowaną „pułapkę” ...


Funkcje nie mogą być zagnieżdżone w powłoce. Nie ma zamknięć. Czy miałeś na myśli wyrwanie się ze wszystkich, z wyjątkiem najbardziej zewnętrzny zakres? Innermost nie ma sensu.
ormaaj

@ormaaj: Wszystkie z nich z najbardziej wewnętrzna funkcja.
Dennis

Ahh ok, gotcha.
ormaaj

Odpowiedzi:


1

Dość brzydkim, ale łatwym sposobem osiągnięcia tego celu byłoby zdefiniowanie zmiennej STOP i sprawdzenie jej po każdym wywołaniu funkcji:

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

Nie jest ładny, ale działa w bash i zsh.


1

Oto niekoniecznie przenośny hack, który wyskakuje ze wszystkich wymaganych poziomów omijając wszystkie RETURN pułapki, skutecznie uniemożliwiają zwracanie czegokolwiek poza 0, i prawdopodobnie jest to błąd przynajmniej pod pewnymi względami. Ta konkretna implementacja jest tylko Bash, ale może być dostosowana do innych powłok.

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

wydajność

Current level: 0
Current level: 1
Current level: 2
Current level: 3
Current level: 4
Current level: 5
Returning from level: 0

0

Przechowywałem całą logikę w oddzielnym skrypcie powłoki zamiast używać funkcji. Wyjście całkowicie wyłączy skrypt i pozwoli skryptowi opakowania kontynuować wykonywanie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.