Wie kann die Bash-Funktion vor dem Überschreiben geschützt werden?

12

In der bashSchale, können wir eine Funktion definieren , fmit

f(){ echo Hello; }

und dann erneut deklarieren / überschreiben mit

f(){ echo Bye; }

Ich glaube, es gibt eine Möglichkeit, Funktionen auf diese Weise davor zu schützen, überschrieben zu werden.

kyb
quelle
2
die gleichen wie bei Variablen, mit typeset -r: typeset -rf f.
Mosvy
3
oderreadonly -f f
mosvy

Antworten:

25

Sie können fmit readonly -f foder declare -g -r -f f( readonlyentspricht declare -g -r) als schreibgeschützte Funktion deklarieren . Es ist die -fOption für diese integrierten Dienstprogramme, mit der sie fals Name einer Funktion und nicht als Variable fungieren 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

Wie Sie sehen, schützt das Festlegen des Schreibschutzes die Funktion nicht nur vor dem Überschreiben, sondern auch vor dem Deaktivieren (vollständiges Entfernen).


Derzeit (ab bash-5.0.11) würde der Versuch, eine schreibgeschützte Funktion zu ändern, die Shell nicht beenden, wenn die errexitShell-Option ( set -e) verwendet wird. Chet, der bashBetreuer, sagt, dass dies ein Versehen ist und dass es mit der nächsten Veröffentlichung geändert wird.

Kusalananda
quelle
Der Versuch, die Funktion zu überschreiben, erzeugt eine Meldung bash: f: readonly functionund einen Statuscode ungleich Null, wird jedoch nicht beendet, wenn die errexitOption aktiviert ist.
kyb
@kyb Das ist mir auch aufgefallen. Ich bin nicht sicher , ob es ein Fehler ist bash, aber ich werde auf einer der bashMailinglisten nachfragen , um sicherzugehen.
Kusalananda
Gut, bitte aktualisieren Sie Ihre Antwort, wenn Sie sich über dieses Verhalten sicher sind.
kyb
1
@kyb Sowohl Stephane Chazelas als auch Greg Wooledge haben diese Frage mit plausiblen Erklärungen beantwortet. Stephane schlägt vor, dass bashnur dann beendet set -ewird, wenn POSIX dies erfordert (und readonly -fnicht POSIX). Greg weist darauf hin, dass das bashHandbuch niemals "Fehler in der Funktionsdeklaration" als Grund für errexitdas Auslösen eines Exits erwähnt (es sei denn, eine Funktionsdeklaration zählt als zusammengesetzter Befehl, was er ziemlich sicher nicht tut). Der Thread läuft hier: lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda
@kyb Mir ist auch aufgefallen, dass Sie nie etwas über errexitoder set -ein Ihrer Frage sagen .
Kusalananda