Come proteggere la funzione bash dall'essere sovrascritta?


13

Nella bashshell, possiamo definire una funzione fcon

f(){ echo Hello; }

e quindi rideclarlo / sovrascriverlo, senza alcun errore o messaggio di avviso, con

f(){ echo Bye; }

Credo che ci sia un modo per proteggere le funzioni dall'override in questo modo.


2
lo stesso che con le variabili, con typeset -r: typeset -rf f.
mosvy,

3
oppurereadonly -f f
mosvy,

Risposte:


25

È possibile dichiarare fcome funzione di sola lettura utilizzando readonly -f fo declare -g -r -f f( readonlyè equivalente a declare -g -r). È l' -fopzione per queste utility integrate che le fa agire fcome il nome di una funzione, piuttosto che sulla variabile f.

$ f(){ echo Hello; }
$ readonly -f f
$ f(){ echo Bye; }
bash: f: readonly function
$ unset -f f
bash: unset: f: cannot unset: readonly function
$ f
Hello

Come puoi vedere, rendere la funzione di sola lettura non solo la protegge dall'essere sovrascritta, ma la protegge anche dall'essere disinserita (rimossa completamente).


Attualmente (a partire da bash-5.0.11), provare a modificare una funzione di sola lettura non terminerebbe la shell se si utilizza l' errexitopzione shell ( set -e). Chet, il bashmanutentore, afferma che questa è una svista e che verrà modificata con la prossima versione.


Il tentativo di sovrascrivere la funzione produce un messaggio bash: f: readonly functione un codice di stato diverso da zero, ma non termina se l' errexitopzione è abilitata.
Kyb,

@kyb Ho notato anche questo. Non sono sicuro che sia un bug bash, ma chiederò una bashmailing list per esserne sicuro.
Kusalananda

bene, ti preghiamo di aggiornare la tua risposta quando sarai sicuro di questo comportamento.
Kyb,

1
@kyb Sia Stephane Chazelas che Greg Wooledge si sono concentrati su questa domanda, entrambi con spiegazioni plausibili. Stephane suggerisce che bashesce solo quando set -eè in vigore quando POSIX lo richiede (e readonly -fnon è POSIX). Greg sottolinea che il bashmanuale non menziona mai il "fallimento nella dichiarazione di funzione" come motivo per errexitinnescare un'uscita (a meno che una dichiarazione di funzione non valga come un comando composto, che è abbastanza sicuro che non lo faccia). Il filo è in corso qui: lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda

@kyb Sto anche notando che non hai mai detto nulla errexito set -enella tua domanda.
Kusalananda
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.