In the bash shell, we can define a function f with

f(){ echo Hello; }

and then redeclare/override it, without any error or warning messages, with

f(){ echo Bye; }

I believe there is a way to protect functions from being overridden in this way.

  • 2
    the same as with variables, with typeset -r: typeset -rf f. – mosvy Sep 26 '19 at 7:25
  • 3
    or readonly -f f – mosvy Sep 26 '19 at 7:26

You may declare f as a read-only function using readonly -f f or declare -g -r -f f (readonly is equivalent to declare -g -r). It's the -f option to these built-in utilities that makes them act on f as the name of a function, rather than on the 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

As you can see, making the function read-only not only protects it from getting overridden, but also protects it from being unset (removed completely).

Currently (as of bash-5.0.11), trying to modify a read-only function would not terminate the shell if one is using the errexit shell option (set -e). Chet, the bash maintainer, says that this is an oversight and that it will be changed with the next release.

  • Attempt to override function produces message bash: f: readonly function and non-zero status code, but does not exit if errexit option enabled. – kyb Sep 27 '19 at 9:55
  • @kyb I noticed this as well. I'm not certain it's a bug in bash, but I will ask on one of the bash mailing lists to be sure. – Kusalananda Sep 27 '19 at 10:03
  • good, please update your answer when you will be sure about this behavior. – kyb Sep 27 '19 at 14:19
  • 1
    @kyb Both Stephane Chazelas and Greg Wooledge weighed in on that question, both with plausible explanations. Stephane suggests that bash only exits when set -e is in effect when POSIX requires it to (and readonly -f is not POSIX). Greg points out that the bash manual never mentions "failure in function declaration" as reason for errexit to trigger an exit (unless a function declaration counts as a compound command, which he's pretty sure it does not). The thread is ongoing here: lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html – Kusalananda Sep 27 '19 at 20:54
  • @kyb I'm also noticing that you never say anything about errexit or set -e in your question. – Kusalananda Sep 27 '19 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.