bash関数がオーバーライドされないようにする方法は?


12

ではbash、シェル、我々は関数を定義することができf

f(){ echo Hello; }

そして、エラーまたは警告メッセージなしで、再宣言/上書きします。

f(){ echo Bye; }

この方法で機能がオーバーライドされるのを防ぐ方法があると思います。


2
変数を使用した場合と同じtypeset -rですtypeset -rf f
mosvy

3
またはreadonly -f f
モスビー

回答:


25

またはfを使用して読み取り専用関数として宣言できます(と同等です)。これらの組み込みユーティリティのオプションは、変数ではなく関数の名前として機能するようにします。readonly -f fdeclare -g -r -f freadonlydeclare -g -r-fff

$ 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

ご覧のとおり、関数を読み取り専用にすることで、オーバーライドされないようにするだけでなく、設定が解除される(完全に削除される)ことも防ぎます。


現在(現在bash-5.0.11)、読み取り専用関数を変更しようとしても、errexitシェルオプション(set -e)を使用している場合、シェルは終了しません。bashメンテナーのChet は、これは見落としであり、次のリリースで変更されると言っています。


関数をオーバーライドしようとすると、メッセージbash: f: readonly functionとゼロ以外のステータスコードが生成されますが、errexitオプションが有効な場合は終了しません。
kyb

@kyb私もこれに気づきました。のバグかどうかbashbashわかりませんが、メーリングリストのいずれかで確認してください。
クサラナンダ

この動作について確信が持てたら、回答を更新してください。
kyb

1
@kybステファン・チャゼラスとグレッグ・ウーレッジの両方が、もっともらしい説明で、その質問について議論しました。Stephaneは、POSIX が必要とする(POSIX ではない)ときに有効であるときにbashのみ終了することを提案します。グレッグは、マニュアルでは出口をトリガーする理由として「関数宣言の失敗」に言及していないことを指摘しています(関数宣言が複合コマンドとしてカウントされている場合を除き、彼はそうではないと確信しています)。スレッドはここで継続中です。lists.gnu.org / archiveset -ereadonly -fbasherrexit
html

@kybまた、質問について、errexitまたはset -e質問で何も言わないことにも気付いています。
クサラナナンダ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.