Hi, All!
Светит мне разработка некоторой системы скриптов на баше, на пару тысяч строк. Не надо сразу писать, что такое не стоит писать на баше — это условие задачи, и ставил его не я.
И решил я по такому поводу попробовать широко распространенный совет: «everything is function». А если придерживаться другой популярной концепции, «everything is local», и третьей («arrays wherever possible»), то тут возникает вопрос о передаче параметров внутрь функции, и о добыче результатов из нее.
Насколько мне известно, баш не обладает возможностями передать массив как массив — штатная передача внутрь как "${array[*]}"
разворачивает массив в строку, что обесценивает оригинальную идею.
Можно передавать внутрь ссылку на массив. Но, во-первых, это только с v4.3 работает. Во-вторых, вот способ, который мне понравился больше:
#!/bin/bash
set -o nounset
set -o errexit
set -o pipefail
f1() {
local var1="${f1_data[var1]}"
local ttt
local i=0
while [[ "${f1_data[var2.$i]:-}" ]]; do
ttt="${ttt:-} ${f1_data[var2.$i]}"
let i=$i+1
done
ttt="${ttt:-} --- ${var1}"
eval "$1='${ttt}'"
unset f1_data
}
main() {
local -A f1_data=(
[var1]="v1"
[var2.0]="bebe"
[var2.1]="oo"
[var2.2]="rwx"
)
local result_var="some default"
f1 result_var \
|| echo "ALARM!" >&2
echo "And the result is \"${result_var}\"!"
}
main
Т.е. непосредственно перед вызовом функции все, что ей надо, засовывается в массив с именем [function_name]_data, который обнуляется в конце работы функции. Я использовал ассоциативный массив, но это просто мне так больше нравится.
Да, и про передачу значения наружу тоже в этом же примере.
Использование eval
позволяет избавиться от необходимости передавать значение наружу через echo
что, в свою очередь, позволяет изящнее организовать обработку ошибок вызова функций.
Ваше мнение?
Буду благодарен за критику и советы.