Вопрос или проблема
Наши серверы RHEL8 не имеют доступной команды ‘nc’, но в какое-то время в прошлом кто-то, использующий эту общую учетную запись, определил функцию ‘nc’:
$ declare -f nc | head -1
nc ()
$
Я пытаюсь выяснить, где определена эта функция:
$ (shopt -s extdebug; declare -F nc)
nc 0 environment
$
Я ожидал увидеть номер строки и имя файла там, и, как вы видите, я получил “0 environment” вместо этого. Может кто-нибудь сказать, что это значит, пожалуйста?
Это говорит нам о том, что функция nc
была определена bash при старте, когда она нашла переменную BASH_func_nc%%
в своей среде:
$ env BASH_FUNC_nc%%='() { echo nc; }' bash -c 'shopt -s extdebug; declare -F nc'
nc 0 environment
Это обычно происходит, когда bash
была вызвана другой инстанс bash
(где-то в её предках), который определил функцию nc
и экспортировал её с помощью export -f nc
.
bash-5.2$ nc() { echo nc; }
bash-5.2$ export -f nc
bash-5.2$ shopt -s extdebug
bash-5.2$ declare -F nc
nc 1 main
bash-5.2$ printenv BASH_FUNC_nc%%
() { echo nc
}
bash-5.2$ bash -c 'shopt -s extdebug; declare -F nc'
nc 0 environment
Ответ или решение
Обзор bash declare built-in и его применение в контексте
Вопрос, касающийся использования команды declare
в контексте Bash, особенно когда речь идет о функции, такой как nc
, требует глубокого понимания механизма формирования и работы функций в среде оболочки Bash.
Что такое Bash declare?
Команда declare
в Bash — это встроенная команда, позволяющая создавать или объявлять переменные, а также функции и управлять их характеристиками, такими как тип, область видимости и другие специальные атрибуты. В данном контексте команда declare -f
используется для отображения определений функций, а declare -F
— для показа краткой информации о функциях, включая имя, статус и местоположение.
Проблема с функцией ‘nc’
Из вашего описания видно, что на серверах RHEL8 отсутствует утилита nc
, но в среде исполнения оболочки уже была определена функция с тем же именем. Когда вы выполняете команду declare -f nc
, вы получаете вывод, показывающий, что функция nc
существует, но не указывает, откуда она была определена.
При выполнении команды:
(shopt -s extdebug; declare -F nc)
вы получаете вывод nc 0 environment
. Этот вывод говорит о том, что функция была определена в окружении, а не в скрипте или интерактивной оболочке, что было бы указано при наличии номера строки или имени файла.
Почему вывод ‘0 environment’?
В Bash, если функция было определено в одной из родительских оболочек (в частности, если она была экспортирована с помощью команды export -f
), её определение сохраняется в специальной переменной окружения с именем BASH_FUNC_имя%%
. В вашем случае это будет BASH_FUNC_nc%%
. Это указывает на то, что функция была установлена в окружении в процессе инициализации другой инстанции Bash.
В последнем примере, когда вы вызываете новую оболочку Bash с опцией bash -c
, вы видите:
$ env BASH_FUNC_nc%%='() { echo nc; }' bash -c 'shopt -s extdebug; declare -F nc'
Это демонстрирует, что в новой оболочке является доступной функция nc
, установленная в родительской оболочке.
Как определить источник определения функции?
Для того чтобы узнать, откуда именно была создана функция, можно использовать следующие шаги:
- Проверить все переменные окружения в родительских оболочках, включая
BASH_FUNC_nc%%
. - Просмотреть конфигурационные файлы и скрипты, которые могли быть загружены в родительских оболочках (например,
~/.bashrc
,~/.bash_profile
). - Проверить, не используется ли окружение для автоматического экспорта функций в зависимости от используемого программного обеспечения или конфигурации оболочки.
Заключение
Таким образом, вывод nc 0 environment
, который вы наблюдаете, подчеркивает важность управления функциями в Bash и то, как функции могут наследоваться из родительской оболочки через установку переменных окружения. Понимание этого аспекта Bash может помочь в выявлении проблем и оптимизации работы с функциями и biếnными, особенно в многопользовательских или серверах, где доступ к общим ресурсам может привести к неожиданным конфликтам.