Поиск по сайту:

Bash-функции и локальные переменные


Эта статья продемонстрирует, как функции локальных переменных используются и создаются в Bash. Создание функций Bash позволяет сделать ваш код более структурированным, а локальные переменные помогают обеспечить безопасность и избежать ошибок в коде. Нырнуть в!

Что такое функции Bash?

Как и другие языки программирования, Bash позволяет создавать функции внутри вашего кода или скрипта. Функция может быть определена для выполнения конкретной задачи или набора задач, и ее можно легко и быстро вызывать из вашего основного кода, просто используя имя, данное функции.

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

Простая функция Bash

Мы определяем test.sh с помощью нашего текстового редактора следующим образом:

#!/bin/bash

welcome(){
echo "welcome"
}

welcome

Затем мы делаем этот файл исполняемым, добавляя свойство execute (x) и выполняем скрипт:

chmod +x test.sh
./test.sh

Мы можем видеть, как скрипт сначала определяет функцию welcome(), используя идиомы Bash function_name() и {} функциональные оболочки. Наконец, мы вызываем функцию welcome, просто используя ее имя welcome.

Когда скрипт выполняется, в фоновом режиме происходит то, что определение функции отмечается, но пропускается (т. е. не выполняется), пока немного ниже не будет нажат вызов функции welcome, Интерпретатор Bash выполняет функцию welcome и возвращается к строке сразу после последующего вызова функции, что в данном случае является концом нашего скрипта.

Передача переменных в функции Bash

Мы определяем файл test2.sh с помощью нашего любимого текстового редактора (vi ;) следующим образом:

#!/bin/bash

if [ -z "${1}" ]; then 
  echo "One option required!"
  exit 1
fi

func1(){
  echo "${1}"
}

func2(){
  echo "${2} ${1}"
}

func1 "${1}"
func2 "a" "b"

Мы снова делаем наш скрипт исполняемым с помощью chmod +x test2.sh и выполняем то же самое.

Полученный результат может показаться интересным или даже запутанным поначалу. Тем не менее, это логично и легко следовать. Первый параметр, переданный сценарию, будет глобально доступен внутри кода как $ {1}, за исключением внутренних функций, где $ {1} становится первым параметром, переданным функции, $ {2} — вторым и т. д.

Другими словами, глобальная переменная $ {1} (первая опция, переданная сценарию из командной строки) недоступна внутри функций, где значение &# 36 Переменная {1} изменяется на первую опцию, переданную функции. Подумайте об иерархии или подумайте о том, как функция может представлять небольшой сценарий сама по себе, и вскоре это обретет смысл.

В качестве примечания можно также использовать $1 вместо $ {1}, но я настоятельно рекомендую начинающим кодировщикам Bash всегда окружать имена переменных { и .

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

Таким образом, мы начинаем нашу программу с глобальной переменной $ {1}, для которой задано значение \first\. Если вы посмотрите на вызов func1, вы увидите, что мы передаем эту переменную в функцию, таким образом, $ {1} внутри функции становится тем, что было в $ {1} программы, т.е. \first\, поэтому первая строка вывода действительно first .

Затем мы вызываем func2 и передаем в функцию две строки \a\ и \b\. Затем они автоматически становятся $ {1} и $ {2} внутри функции func2. Внутри функции мы печатаем их в обратном порядке, и наш вывод хорошо совпадает с b a в качестве второй строки вывода.

Наконец, мы также делаем проверку в верхней части нашего скрипта, которая гарантирует, что опция действительно передается в скрипт test2.sh, проверяя, \$ {1}\ пуст или не использует тест -z внутри команды if. Мы выходим из скрипта с ненулевым кодом выхода (exit 1), чтобы указать всем вызывающим программам, что что-то пошло не так.

Локальные переменные и возвращаемые значения

Для нашего последнего примера мы определяем сценарий test3.sh следующим образом:

#!/bin/bash

func3(){
  local REVERSE="$(echo "${1}" | rev)"
  echo "${REVERSE}"
}

INPUT="abc"
REVERSE="$(func3 "${INPUT}")"
echo "${REVERSE}"

Снова делаем его исполняемым и выполняем скрипт. Результатом будет cba, как и следовало ожидать, просмотрев код и отметив имена переменных и т. д.

Однако код сложный и требует некоторого привыкания. Давайте исследовать.

Во-первых, мы определяем функцию func3, в которой мы создаем локальную переменную с именем REVERSE. Мы присваиваем ей значение, вызывая подоболочку ($()), и внутри этой подоболочки мы повторяем все, что было передано функции ($ {1}) и передайте этот вывод команде rev.

Команда rev выводит ввод, полученный из канала (или иным образом), в обратном порядке. Также интересно отметить, что переменная $ {1} остается внутри подоболочки! Это прошлое интегрально.

Затем, все еще из функции func3, мы печатаем вывод. Однако этот вывод не будет отправлен на экран, а будет захвачен самим вызовом нашей функции и, таким образом, сохранен в переменной ‘global’ REVERSE.

Мы устанавливаем наш ввод в \abc\, снова вызываем функцию func3 из подоболочки, передавая переменную INPUT, и присваиваем вывод в переменную REVERSE. Обратите внимание, что между переменной 'global' REVERSE и переменной local REVERSE внутри скрипта нет абсолютно никакой связи. .

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

#!/bin/bash

func3(){
  local REVERSE="$(echo "${1}" | rev)"
  echo "${REVERSE}"
}

INPUT="abc"
REVERSE="test"
func3 "${INPUT}"
echo "${REVERSE}"

При выполнении выводятся cba и test. cba на этот раз генерируется тем же echo \$ {REVERSE}\ внутри функции func3, но на этот раз выводить напрямую, а не захватывать в приведенном ниже коде, поскольку функция func3 \$ {INPUT}\ не вызывается из подоболочки.

Этот сценарий подчеркивает два момента обучения, которые мы рассмотрели ранее: во-первых, несмотря на то, что мы установили переменную REVERSE в значение \test\ внутри сценария перед вызовом функция func3 – что локальная переменная REVERSE берет верх и используется вместо 'глобальной'.

Во-вторых, наша переменная 'global' REVERSE сохраняет свое значение, даже если внутри вызываемой функции использовалась local переменная с таким же именем. функция3.

Подведение итогов

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

Здесь также следует отметить, что помимо улучшенной читаемости кода и простоты использования, использование локальных переменных обеспечивает дополнительную безопасность, поскольку переменные не будут доступны вне контекста функции и т. д. Наслаждайтесь функциями и локальными переменными при написании кода в Баш!

Если вы хотите узнать больше о Bash, ознакомьтесь с нашими статьями «Как правильно анализировать имена файлов в Bash» и «Использование xargs в сочетании с bash -c для создания сложных команд».