Ferma le funzioni bash bloccando le variabili globali


0

Ecco un estratto da uno script bash per riconfigurare grub

    OLD="/etc/default/grub"
    NEW="/tmp/default.grub"
    SEC="1"

    cp "$OLD" "$NEW" || { >&2 echo "Couldn't copy $OLD" && exit 1; }

    sed -i "s/GRUB_TIMEOUT=[0-9]\+/GRUB_TIMEOUT=3/$SEC" "$NEW"

    cp_if_change_confirmed "$NEW" "$OLD"

    diff "$OLD" "$NEW" >/dev/null 2>&1 && \
    {
        CFG="$NEW.made"

        grub2-mkconfig --output="$CFG"

        echo "made $CFG from $NEW"

        cp_if_change_confirmed "$CFG" "/boot/grub2/grub.cfg"

        echo rm "$CFG"
        rm "$CFG"
    }

    echo rm "$NEW"
    rm "$NEW"

Quelle finali echoe rmlinee di output

rm /tmp/default.grub.made
rm /tmp/default.grub.made
rm: cannot remove ‘/tmp/default.grub.made:‘ No such file or directory

In qualche modo NEWviene assegnato il valore di CFG.

Guardando dentro cp_if_change_confirmed, che è una funzione bash, contiene

NEW="$1"

Il che suppongo spieghi il problema: queste variabili non hanno un ambito abbastanza limitato.

Ma questo è un problema di manutenzione: devo essere in grado di includere funzioni di terze parti e sapere che non intaccheranno i valori nello script principale.

Posso farlo in bash o è un caso senza speranza e devo solo essere vigile sui nomi delle variabili o usare un linguaggio reale?


Nelle funzioni, utilizzare local. Un vero linguaggio avrebbe senso per script più grandi, con Perl o Ruby non devi andare così lontano dalla sintassi della shell.
Choroba,

Risposte:


1

Usa local. Nota che bash ha solo un ambito di funzione (come varin JavaScript), non un ambito di blocco.

myfunc() {
    local foo bar=$1 baz=$2
    foo=/tmp/$bar
    echo "value inside: $foo, $bar"
}
foo=123 bar=234
myfunc quux
echo "value outside: $foo, $bar"

Se si dispone di un blocco che non ha bisogno di alcun persistenza, è possibile chiamare una subshell tramite ( ... ):

foo=123
( foo=345; echo "value inside: $foo" )
echo "value outside: $foo"

Si noti che i subshells hanno l'intero overhead di fork () - sono processi indipendenti. Inoltre, non ti consentono di scegliere quali variabili localizzare: è tutto o niente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.