Як захистити функцію bash від перекриття?


13

У bashоболонці ми можемо визначити функцію за fдопомогою

f(){ echo Hello; }

а потім передекларувати / замінити, без помилок або попереджувальних повідомлень, за допомогою

f(){ echo Bye; }

Я вважаю, що існує спосіб захистити функції від перекриття таким чином.


2
так само , як зі змінними, з typeset -r: typeset -rf f.
mosvy

3
абоreadonly -f f
mosvy

Відповіді:


25

Ви можете оголосити fфункцію лише для читання, використовуючи readonly -f fабо declare -g -r -f f( readonlyеквівалентно declare -g -r). Саме -fці вбудовані утиліти змушують їх діяти fяк ім'я функції, а не змінної 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

Як бачите, робить функція лише для читання не тільки захищає її від перекриття, але й захищає від невстановлення (видалення повністю).


В даний час (станом на bash-5.0.11) спроба змінити функцію лише для читання не припиняє оболонку, якщо використовується errexitопція оболонки ( set -e). Чет, керівник bash, каже, що це нагляд і що це буде змінено наступним випуском.


Спроба переосмислити функцію створює повідомлення bash: f: readonly functionта ненульовий код статусу, але не виходить, якщо errexitпараметр включений.
киб

@kyb Я також це помітив. Я не впевнений, що це помилка bash, але я попрошу в одному зі bashсписків розсилки бути впевненим.
Kusalananda

добре, будь ласка, оновіть свою відповідь, коли ви будете впевнені в такій поведінці.
киб

1
@kyb І Стефан Шазелас, і Грег Вуоледж зважилися на це питання, обидва з правдоподібними поясненнями. Стефан припускає, що bashвін закривається лише тоді, коли set -eдіє, коли POSIX вимагає цього (а readonly -fне POSIX). Грег зазначає, що в bashпосібнику ніколи не згадується "збій у оголошенні функції" як причина для errexitзапуску виходу (якщо тільки декларація функції не вважається складною командою, що він впевнений, що це не так). Тема продовжується тут: list.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda

@kyb Я також зауважую, що ти ніколи нічого не кажеш про своє запитання errexitчи про set -eце.
Kusalananda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.