Практическое написание сценариев командной оболочки Bash/Эмуляция ссылочной адресации: различия между версиями

Содержимое удалено Содержимое добавлено
Нет описания правки
Строка 245:
Enter your id: 1
Error: This id is unknown to the system.
</source>
 
== Косвенная адресация средствами Bash ==
 
Начиная с версии Bash 4.3 стабильно можно косвенно ссылаться на переменные средствами самой командной оболочки. Следующие методы вообще не переносятся между разными командными оболочками и ими стоит пользоваться только, когда вы пишите только для Bash.
 
Для начала рассмотрим самый простой случай.
<source lang=bash>
ORIGIN_VARIABLE='Some value' # Это простая переменная с некоторым значением, на которое мы сошлемся косвенно через ссылку.
REF='ORIGIN_VARIABLE' # Переменная REF (ссылка) хранит имя переменной, на которую ссылается.
 
# Примечание: в данном случае не обязательно ставить одинарные кавычки при присваивании имени переменной ссылке.
# Мы так делаем, потому что строковые литералы подсвечиваются другим цветом, если текстовый редактор умеет подсвечивать
# код на Bash.
 
# Чтобы подставить значение по ссылке, вы должны воспользоваться следующей специальной подстановкой:
echo "${!REF}" # Ссылка будет разрешена интерпретатором. Результат подстановки: "Some value"
</source>
 
Можно обозначить ссылку явно через команду <code>declare</code> с опцией <code>-n</code>. Эта опция аналогична команде <code>nameref</code> в Ksh. Явное объявление ссылок улучшает читаемость кода, так как передает ваши намерения явно.
<source lang=bash>
declare -n REF='ORIGIN_VARIABLE'
</source>
 
На практике чаще всего ссылки передаются в универсальные функции, которые могут пользоваться ими, чтобы записать результат своей работы. Следующий пример демонстрирует функцию, которая ищет максимальное и минимальное значения в любом простом массиве (конечно опуская различные проверки).
<source lang=bash>
#!/bin/bash
 
declare -a ARRAY=(5 6 -1 7 5 10 8 7 12 -8 4)
 
min_max() {
local refarr=${1}[@] # Это ссылка на передаваемый фунции массив. Ссылки на массивы мы обсудим позже.
local -n min=$2 # Это ссылка на выходную переменную, в которую мы запишем минимальное значение.
local -n max=$3 # Это ссылка на выходную переменную, в которую мы запишем максимальное значение.
min=${1}[0]
max=${1}[0]
for element in "${!refarr}"; do
((min = element < min ? element : min))
((max = element > max ? element : max))
done
}
 
min_max ARRAY minval maxval # Вызов функции.
# Обратите внимание, что мы передаем функции имена объектов, с которыми функция внутри работает через ссылки,
# что позволяет не привязываться к конкретным именам в реализации функции.
 
echo "Min value: $minval"
echo "Max value: $maxval"
</source>
Результат работы:
<source lang=bash>
Min value: -8
Max value: 12
</source>