Я пытаюсь передать массив в функцию, и любые изменения, внесенные в массив, отражаются за пределами функции.
function update_array()
{
${1[0]}="abc" # trying to change zero-index array to "abc" ,
# bad substitution error
}
foo=(foo bar)
update_array foo[@]
for i in ${foo[@]}
do
echo "$i" # currently changes are not reflected outside the function
done
Мои вопросы:
1) Как получить доступ к индексный массив, например: нулевой индексный массив, в функции, каков синтаксис для него
2) Как я могу внести изменения в этот индексный массив, чтобы изменения отражались и вне функции
Несколько проблем, в логическом порядке фиксации:
С Вашим ${...}
оператор в update_array()
, ${..}
синтаксис для использования переменной, не определяют его.
Пример:
foo[0]=abc # assigns 'abc' to foo[0]
При работе вокруг этого имя массива хранится в переменной.
Не работа:
$1[0]=abc
Работа:
declare -g "$1[0]=abc" # -g arg is for a global variable
Передача аргумента update_array()
должен передать имя переменной (foo
в этом случае), не содержание массива. foo[@]
ничего специального, это - абсолютно нормальная строка (в Bash).
Переменное расширение с ${foo[@]}
должен быть дважды заключен в кавычки.
Рабочая версия кода ниже:
update_array() {
declare -g "$1[0]=abc"
}
foo=(foo bar)
update_array foo
for i in "${foo[@]}"; do
echo "$i"
done
## Following line added by me for further clarification
declare -p foo
который печатает, правильно:
abc
bar
declare -a foo='([0]="abc" [1]="bar")'
Объявление переменных в Bash может не потребоваться. 1 sup> Да, вы можете использовать declare
/ typeset
для большего контроля над вашим bash. переменные. Поэтому я считаю, что вам не нужно создавать функцию только для объявления нового массива.
Этот скрипт ниже демонстрирует прямое определение массива:
#!/bin/bash
function define_array_elements() {
# You can note the array elements being defined directly, without a prior
# definition of the variable.
for i in {1..10}; do
var_name[$i]="Field $i of the list"
done
}
define_array_elements > /dev/null
for i in {1..10}; do
echo "Field $i is: ${var_name[$i]}"
done
(Пример заимствован из Как объявить массив, но не определить его? с небольшой модификацией.)
Краткий ответ: вы не можете. Bash не имеет способа передачи переменных по ссылке, поэтому нет общего способа сделать это; у вас остались (некрасивые) хаки, в том числе косвенные и / или eval.
В следующем выпуске bash 4.3 появятся переменные nameref, которые позволят вам передавать переменные по ссылке, но даже эта функция не дотягивает, так как вы все еще рискуете столкнуться с именем.
# example of passing variables by reference in bash 4.3
update_array() {
declare -n array=$1
array[0]=abc
}
foo=( foo bar )
update_array foo
printf '<%s>\n' "${foo[@]}" # outputs <abc> and <bar>
В этом примере, если массив был назван array
вместо foo
, он потерпит неудачу, поскольку declare -n array=array
является ошибкой (declare: array: nameref variable self references not allowed
).
См. http://mywiki.wooledge.org/BashFAQ/006 для других хаков.