¿Cómo proteger la función bash de ser anulada?

13

En el bashshell, podemos definir una función fcon

f(){ echo Hello; }

y luego redeclararlo / anularlo, sin ningún mensaje de error o advertencia, con

f(){ echo Bye; }

Creo que hay una manera de proteger las funciones de ser anuladas de esta manera.

kyb
fuente
2
lo mismo que con las variables, con typeset -r: typeset -rf f.
mosvy
3
oreadonly -f f
mosvy

Respuestas:

25

Puede declarar fcomo una función de solo lectura usando readonly -f fo declare -g -r -f f( readonlyes equivalente a declare -g -r). Es la -fopción de estas utilidades integradas lo que hace que actúen fcomo el nombre de una función, en lugar de sobre la variable 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

Como puede ver, hacer que la función de solo lectura no solo la proteja de ser anulada, sino que también la protege de ser desarmada (eliminada por completo).


Actualmente (a partir de bash-5.0.11), intentar modificar una función de solo lectura no terminaría el shell si se usa la errexitopción de shell ( set -e). Chet, el bashmantenedor, dice que esto es un descuido y que se cambiará con la próxima versión.

Kusalananda
fuente
Intentar anular la función produce un mensaje bash: f: readonly functiony un código de estado distinto de cero, pero no sale si la errexitopción está habilitada.
kyb
@kyb También noté esto. No estoy seguro de que haya un error bash, pero preguntaré en una de las bashlistas de correo para estar seguro.
Kusalananda
bien, actualice su respuesta cuando esté seguro de este comportamiento.
kyb
1
@kyb Tanto Stephane Chazelas como Greg Wooledge intervinieron en esa pregunta, ambos con explicaciones plausibles. Stephane sugiere que bashsolo se cierra cuando set -eestá vigente cuando POSIX lo requiere (y readonly -fno es POSIX). Greg señala que el bashmanual nunca menciona la "falla en la declaración de la función" como razón para errexitdesencadenar una salida (a menos que una declaración de función cuente como un comando compuesto, lo cual está bastante seguro de que no lo hace). El hilo está en curso aquí: lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda
@kyb También me doy cuenta de que nunca dices nada al respecto errexito set -een tu pregunta.
Kusalananda