Spec-Zone.ru › Bash

Функции оболочки

​ ​

Функции оболочки позволяют группировать команды для последующего выполнения, используя одно имя для всей группы. Они выполняются так же, как «обычная» простая команда. Когда имя функции оболочки используется в качестве имени простой команды, оболочка выполняет список команд, связанный с этим именем функции. Функции оболочки выполняются в контексте текущей оболочки; для их интерпретации не создается новый процесс.

Функции объявляются с использованием следующего синтаксиса:

fname () compound-command [ redirections ]

или

function fname [()] compound-command [ redirections ]

Так определяется функция оболочки с именем fname. Зарезервированное слово function является необязательным. Если используется зарезервированное слово function, круглые скобки можно не указывать. Тело функции — это составная команда compound-command (см. Составные команды). Обычно эта команда представляет собой list, заключенный между { и }, но может быть любой составной командой из перечисленных выше. Если используется зарезервированное слово function, но круглые скобки не указаны, рекомендуется использовать фигурные скобки. Когда оболочка работает в режиме POSIX (см. Bash и POSIX), fname должно быть допустимым именем оболочки и не должно совпадать с именем одной из специальных встроенных команд (см. Специальные встроенные команды). Вне режима POSIX именем функции может быть любое не заключенное в кавычки слово оболочки, не содержащее ‘$’.

Любая переадресация (см. Переадресации), связанная с функцией оболочки, выполняется при вызове функции. Определения функций удаляются с помощью параметра -f встроенной команды unset (см. Встроенные команды оболочки Bourne).

Статус завершения определения функции равен нулю, если не произошла синтаксическая ошибка и если функция с тем же именем не существует и не является доступной только для чтения. При выполнении функции ее статусом завершения становится статус завершения последней команды, выполненной в ее теле.

Обратите внимание, что по историческим причинам в наиболее распространенном варианте использования фигурные скобки, ограничивающие тело функции, должны отделяться от тела символами blank или переводами строки. Это связано с тем, что фигурные скобки являются зарезервированными словами и распознаются как таковые только в том случае, если отделены от списка команд пробельными символами или другим метасимволом оболочки. При использовании фигурных скобок list должен завершаться точкой с запятой, символом ‘&’ или переводом строки.

compound-command выполняется всякий раз, когда fname указывается в качестве имени простой команды. Функции выполняются в контексте вызывающей оболочки; для их интерпретации не создается новый процесс (в отличие от выполнения сценария оболочки).

При выполнении функции ее аргументы становятся позиционными параметрами на время выполнения (см. Позиционные параметры). Специальный параметр ‘#’, раскрывающийся в количество позиционных параметров, обновляется в соответствии с новым набором позиционных параметров. Специальный параметр 0 не изменяется. Первый элемент переменной FUNCNAME устанавливается в имя функции на время ее выполнения.

Все остальные аспекты среды выполнения оболочки у функции и ее вызывающего кода одинаковы, за следующими исключениями: ловушки DEBUG и RETURN не наследуются, если только функции не был присвоен атрибут trace с помощью встроенной команды declare или не был включен параметр -o functrace с помощью встроенной команды set (в этом случае все функции наследуют ловушки DEBUG и RETURN); ловушка ERR не наследуется, если не включен параметр оболочки -o errtrace. Описание встроенной команды trap см. в разделе Встроенные команды оболочки Bourne.

Переменная FUNCNEST, если ей присвоено числовое значение больше 0, задает максимальный уровень вложенности функций. Вызовы функций, превышающие это ограничение, приводят к прерыванию всей команды.

Если во функции выполняется встроенная команда return, функция завершается, а выполнение продолжается со следующей команды после вызова функции. Перед возобновлением выполнения запускается любая команда, связанная с ловушкой RETURN. После завершения функции значения позиционных параметров и специального параметра ‘#’ восстанавливаются до тех, которые были до выполнения функции. Если команде return передан числовой аргумент, он становится статусом возврата функции; в противном случае статусом возврата функции является статус завершения последней команды, выполненной перед return.

Локальные для функции переменные объявляются с помощью встроенной команды local (локальные переменные). Обычно переменные и их значения являются общими для функции и вызывающего ее кода. Эти переменные видны только внутри функции и командам, которые она вызывает. Это особенно важно, когда функция оболочки вызывает другие функции.

В следующем описании текущая область видимости — это выполняемая в данный момент функция. Предыдущие области видимости включают вызывающий код этой функции и далее по цепочке до «глобальной» области видимости, где оболочка не выполняет никакую функцию оболочки. Локальная переменная в текущей локальной области видимости — это переменная, объявленная с помощью встроенной команды local или declare в выполняемой в данный момент функции.

Локальные переменные «затеняют» переменные с тем же именем, объявленные в предыдущих областях видимости. Например, локальная переменная, объявленная в функции, скрывает переменные с тем же именем, объявленные в предыдущих областях видимости, в том числе глобальные переменные: обращения к переменной и присваивания относятся к локальной переменной, не изменяя переменные в предыдущих областях видимости. Когда функция возвращает управление, глобальная переменная снова становится видимой.

Для управления видимостью переменной внутри функций оболочка использует динамическую область видимости. При динамической области видимости доступные переменные и их значения определяются последовательностью вызовов функций, в результате которой выполнение дошло до текущей функции. Значение переменной, видимое функции, зависит от ее значения в вызывающей функции, если таковая имеется, независимо от того, является ли эта вызывающая функция глобальной областью видимости или другой функцией оболочки. Именно это значение затеняется объявлением локальной переменной и восстанавливается при возврате из функции.

Например, если переменная var объявлена локальной в функции func1, а func1 вызывает другую функцию func2, обращения к var из func2 разрешаются в локальную переменную var из func1, затеняя любую глобальную переменную с именем var.

Следующий сценарий демонстрирует это поведение. При выполнении сценарий выводит

In func2, var = func1 local
func1()
{
    local var='func1 local'
    func2
}

func2()
{
    echo "In func2, var = $var"
}

var=global
func1

Встроенная команда unset также использует ту же динамическую область видимости: если переменная является локальной для текущей области видимости, unset удаляет ее; в противном случае удаление затронет переменную, найденную в любой вызывающей области видимости, как описано выше. Если переменная в текущей локальной области видимости удалена, она остается удаленной (то есть считается неустановленной), пока ей снова не присвоят значение в этой области видимости или пока функция не вернет управление. После возврата из функции становится видимым любой экземпляр переменной из предыдущей области видимости. Если удаление затрагивает переменную в предыдущей области видимости, становится видимым любой экземпляр переменной с таким именем, который был затенен (см. ниже, как параметр оболочки localvar_unset меняет это поведение).

Параметр -f встроенной команды declare (typeset) (см. Встроенные команды Bash) выводит имена и определения функций. Параметр -F команды declare или typeset выводит только имена функций (и, при включенном параметре оболочки extdebug, при необходимости исходный файл и номер строки). Функции можно экспортировать, чтобы они автоматически определялись в дочерних процессах оболочки (создаваемых при отдельном запуске оболочки), с помощью параметра -f встроенной команды export (см. Встроенные команды оболочки Bourne). Параметр -f встроенной команды unset (см. Встроенные команды оболочки Bourne) удаляет определение функции.

Функции могут быть рекурсивными. Переменную FUNCNEST можно использовать, чтобы ограничить глубину стека вызовов функций и количество вызовов функций. По умолчанию Bash не ограничивает количество рекурсивных вызовов.

Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/bash/manual/html_node/Shell-Functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API