
Могу ли я использовать переменную внутри синтаксиса ()
#!/bin/bash
declare -A c
declare -A b
a="[a]=0 [b]=1 [c]=2 [d]=3"
b=($a) # or b=($(echo "$a"))
echo "***********${b[@]}*********" #********************
c=([a]=0 [b]=1 [c]=2 [d]=3)
echo "---------${c[@]}----------" #---------0 1 2 3----------
решение1
В настоящее время (насколько мне известно) невозможно брать строки и создавать с ними ассоциативные массивы в Bash. Поэтому вы должны "оценить" их перед использованием оператора eval
.
При запуске вашего примера с использованием Bash версии 4.1.7 я получаю следующее:
$ ./arr.bash
./arr.bash: line 5: b: [a]=0: must use subscript when assigning associative array
./arr.bash: line 5: b: [b]=1: must use subscript when assigning associative array
./arr.bash: line 5: b: [c]=2: must use subscript when assigning associative array
./arr.bash: line 5: b: [d]=3: must use subscript when assigning associative array
Изменение строки на эту работает:
eval "b=($a)" # or b=($(echo "$a"))
Повторив запуск, вы получите ожидаемые результаты:
$ ./arr.bash
***********0 1 2 3*********
---------0 1 2 3----------
Объяснение
Я нашел этот SO Q&A под названием:Bash: Как присвоить ассоциативный массив другому имени переменной (например, переименовать переменную)?, который иллюстрирует метод, позволяющий это сделать, declare
но он показывает, насколько нечитабельным на самом деле является этот метод, и, вероятно, его не следует использовать.
# declare associative array
declare -A assoc_array=(["key1"]="value1" ["key2"]="value2")
# convert associative array to string
assoc_array_string=$(declare -p assoc_array)
# create new associative array from string
eval "declare -A new_assoc_array="${assoc_array_string#*=}
# show array definition
declare -p new_assoc_array
Этот метод показывает, что $assoc_array
преобразуется в строку, а затем преобразуется обратно в ассоциативный массив, $new_assoc_array
. Но даже этот метод не может избежать необходимости использовать eval
. Это сложный для понимания фрагмент кода, и он показывает, почему его действительно следует избегать.
решение2
Тебе нужно
eval "b=($a)"
eval
оценит свой аргумент как команду оболочки после выполнения расширения параметра. Однако используйте с осторожностью. Убедитесь, что это $a
не установлено пользовательским вводом, так как это может привести к разного рода проблемам.