如何保护bash函数不被覆盖?使其只读

如何保护bash函数不被覆盖?使其只读

bashshell 中,我们可以定义一个f函数

f(){ echo Hello; }

然后重新声明/覆盖它,没有任何错误或警告消息,

f(){ echo Bye; }

我相信有一种方法可以保护函数不被这种方式覆盖。

答案1

您可以使用or (相当于)将函数声明foo为只读函数。这些内置实用程序的选项使它们充当函数的名称,而不是变量。readonly -f foodeclare -g -r -f fooreadonlydeclare -g -r-ffoofoo

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

正如您所看到的,使函数只读不仅可以防止它被覆盖,还可以防止它被取消设置(完全删除)。


目前(截至),如果使用shell 选项 ( ),bash-5.0.11则尝试修改只读函数不会终止 shell 。 Chet,维护者,errexitset -ebash说这是一个疏忽并且它将在下一个版本中进行更改。

更新:此问题已于 2019 年 10 月修复,因此,如果在shell 选项处于活动状态时尝试修改只读函数,则bash-5.1-alpha任何5.1 或更高版本都将正确退出。basherrexit

答案2

对@Kusalananda 的回答没什么评论。根据 bash 维护者的说法,在使用 .bashrc 时,更改只读函数将触发 shell 的终止set -e

我正在使用 Ubuntu 20.10 和更新的 bash 版本。不幸的是它似乎被打破了。

$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)

测试文件

#!/usr/bin/env bash

set -e

test() {
    echo "I'm test() function"
}
readonly -f test

test

test() { # should exit here
    echo "I'm test() function (duplicated)"
}
test

输出

$ chmod +x test.sh; ./test.sh
I'm test() function
./test.sh: line 14: test: readonly function
I'm test() function

我已经使用最新的 bash 版本在 docker 容器内测试了这个脚本,它按预期工作。

GNU bash, version 5.1.8(1)-release (x86_64-pc-linux-musl)

相关内容