bash
シェルではf
関数を定義できます。
f(){ echo Hello; }
その後、エラーや警告メッセージなしで再宣言/再定義します。
f(){ echo Bye; }
私はこのように関数がオーバーライドされないように保護する方法があると思います。
答え1
または、(同じ)を使用して関数をfoo
読み取り専用として宣言することもできます。これらの組み込みユーティリティのオプションを使用すると、そのユーティリティは変数ではなく関数名として機能します。readonly -f foo
declare -g -r -f foo
readonly
declare -g -r
-f
foo
foo
$ 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
ご覧のように、関数を読み取り専用にすることで上書きを防ぐことができるだけでなく、設定解除(完全に削除)も防止できます。
現在の(現在の)bash-5.0.11
シェルオプション()を使用している場合、読み取り専用機能を変更しようとするとシェルは終了しません。チェット、マネージャー、errexit
set -e
bash
間違いだったと言いました。そして、次のバージョンでは変更される予定です。
更新:この問題は2019年10月に解決されたため、bash-5.1-alpha
シェルオプションが有効になっている間に読み取り専用機能を変更しようとすると、5.1以降のバージョンが正しく終了します。bash
errexit
答え2
@Kusalanandaの返信にコメントがありません。 Bash管理者によると、.bashrcを使用しているときに読み取り専用機能を変更すると、シェルは終了します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)