Jak chronić funkcję bash przed nadpisaniem?


13

W bashpowłoce możemy zdefiniować funkcję za fpomocą

f(){ echo Hello; }

a następnie ponownie utwórz / zastąp to, bez żadnych komunikatów o błędach lub ostrzeżeniach, za pomocą

f(){ echo Bye; }

Wierzę, że istnieje sposób na ochronę funkcji przed zastąpieniem w ten sposób.


2
tak samo jak w przypadku zmiennych, z typeset -r: typeset -rf f.
mosvy

3
lubreadonly -f f
mosvy

Odpowiedzi:


25

Możesz zadeklarować fjako funkcję tylko do odczytu, używając readonly -f flub declare -g -r -f f( readonlyjest równoważne declare -g -r). Jest to -fopcja dla tych wbudowanych narzędzi, która sprawia, że ​​działają one fjak nazwa funkcji, a nie na zmiennej 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

Jak widać, ustawienie funkcji tylko do odczytu nie tylko chroni ją przed przesłonięciem, ale także chroni przed rozbrojeniem (całkowicie usuniętym).


Obecnie (stan na dzień bash-5.0.11) próba modyfikacji funkcji tylko do odczytu nie spowodowałaby zakończenia powłoki, jeśli używa się errexitopcji powłoki ( set -e). Chet, bashopiekun, mówi, że jest to przeoczenie i że zostanie zmienione w następnej wersji.


Próba zastąpienia funkcji powoduje wygenerowanie komunikatu bash: f: readonly functioni niezerowy kod stanu, ale nie kończy się, jeśli errexitopcja jest włączona.
kyb

@kyb Zauważyłem to również. Nie jestem pewien, czy to błąd bash, ale zapytam o to na jednej z bashlist mailowych.
Kusalananda

dobrze, zaktualizuj swoją odpowiedź, kiedy będziesz mieć pewność co do tego zachowania.
Kyb

1
@kyb Zarówno Stephane Chazelas, jak i Greg Wooledge zastanawiali się nad tym pytaniem, obaj z prawdopodobnymi wyjaśnieniami. Stephane sugeruje, że bashkończy działanie tylko wtedy, gdy set -edziała, gdy POSIX tego wymaga (i readonly -fnie jest POSIX). Greg zwraca uwagę, że bashpodręcznik nigdy nie wspomina o „niepowodzeniu w deklaracji funkcji” jako przyczynie errexitwywołania wyjścia (chyba że deklaracja funkcji liczy się jako polecenie złożone, co jest prawie pewne, że tak nie jest). Wątek trwa tutaj: lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda

@kyb Ja również zauważyć, że nigdy nie mówią nic na temat errexitlub set -ew swoim pytaniu.
Kusalananda
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.