1-й исключая сотрудником: Как я делаю (что-то тривиальное)?
2-й исключая сотрудником: sudo rm -rf /
1-й исключая сотрудником: Ха-ха хорошо
...
1-й исключая сотрудником (Забывавшим, что он был бы просто sudo
редактор что-то еще, таким образом, это не попросило его пароль снова): о, F ** K!!!
Я думаю, что использование косвенной ссылки переменной удара нужно рассматривать буквально.
Например, Для Вашего исходного примера:
a=(one two three)
echo ${a[*]} # one two three
b=a
echo ${!b[*]} # this would not work, because this notation
# gives the indices of the variable b which
# is a string in this case and could be thought
# as a array that conatins only one element, so
# we get 0 which means the first element
c='a[*]'
echo ${!c} # this will do exactly what you want in the first
# place
Для последнего реального сценария я полагаю, что код ниже сделал бы работу.
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST="LIST_$whichone"[*]
LIST=( "${!_LIST}" ) # Of course for indexed array only
# and not a sparse one
Лучше использовать нотацию "${var[@]}"
которые стараются не портить с $IFS
и расширение параметра. Вот заключительный код.
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST="LIST_$whichone"[@]
LIST=( "${!_LIST}" ) # Of course for indexed array only
# and not a sparse one
# It is essential to have ${!_LIST} quoted
Необходимо скопировать элементы явно. Для индексного массива:
b=("${a[@]}")
Для ассоциативного массива (отмечают это a
название переменной типа массив, не переменная, значение которой является названием переменной типа массив):
typeset -A b
for k in "${!a[@]}"; do b[$k]=${a[$k]}; done
Если у Вас есть имя переменной в массиве, можно использовать поэлементно метод с дополнительным шагом для получения ключей.
eval "keys=(\"\${!$name[@]}\")"
for k in "${keys[@]}"; do eval "b[\$k]=\${$name[\$k]}"; done
(Предупреждение, код в этом сообщении был введен непосредственно в браузере и не протестирован.)
\${!$name[@]}
на первой строке, так, чтобы первое расширение имело только '$name', и ${!a[@]}
сохраняется для оценки и того же самого в для цикла, с \${$name}
. Другие две обратных косых черты, прежде чем '$k' не будут строго необходимы там также.
– krb686
31.10.2016, 01:45
${!b[*]}
расширяется до индексов, используемых в массиве b
.
То, что Вы хотели бы, должно быть сделано на двух шагах, таким образом, eval
поможет: eval echo \${$b[*]}
. (Отметьте \
который гарантирует что первое $
передаст первый шаг, переменное расширение, и будет только расширен на втором шаге со стороны eval
.)
Согласно расширению параметра !
оба используется для косвенного расширения ({!a}
), Имена, соответствующие префиксу (${!a*}
) и Список ключей массива (${!a[*]}
). Поскольку Список ключей массива имеет тот же синтаксис, поскольку Ваше намеченное косвенное expansion+array расширение элемента, позже не поддерживается, как.
${!a}
действительно расширяется до значения переменной, имя которой $a
. Это скорее кратко описано в руководстве в абзаце, который начинается, “Если первый символ параметра является восклицательным знаком (!
), уровень переменной абстракции представлен”.
– Gilles 'SO- stop being evil'
06.09.2011, 10:35
${!
вид ambigious с тех пор, если это - массив, Вы имеете дело с, поведение отличается.
– Eric Smith
06.09.2011, 11:50
Для косвенного доступа к массивам просто добавьте [@]
к косвенной переменной b = a [@]
.
Если эти переменные установлены:
a=(one two three)
printf '<%s> ' "${a[@]}"; echo
Тогда это будет работать:
b="a[@]"
printf '<%s> ' "${!b}"
Или просто:
echo "${!b}"
Такой массив можно скопировать следующим образом:
newArr=( "${!b}" )
А затем напечатать:
declare -p newArr
В одном скрипте:
#!/bin/bash
a=(one two three)
echo "original array"
printf '<%s> ' "${a[@]}"; echo
echo "Indirect array with variable b=a[@]"
b="a[@]"
printf '<%s> ' "${!b}"; echo
echo "New array copied in newArr, printed with declare"
newArr=( "${!b}" )
declare -p newArr
Конечно, все вышеперечисленное скопирует неразреженный массив. Тот, в котором все индексы имеют значение.
разреженные массивы могут иметь неопределенные элементы.
Например, a [8] = 1234
определяет один элемент, а в bash от 0 до 7 не существует.
Чтобы скопировать такой разреженный массив, используйте этот метод
Распечатайте старый массив:
$ oldarr [8] = 1234
$ declare -p oldarr
declare -a oldarr = ( [8] = "1234")
Замените имя массива и запишите строку:
$ str = $ (declare -p oldarr | sed 's / oldarr = / newarr = / ')
Оцените созданную таким образом строку, новый массив определен:
$ eval "$ str"
$ declare -p newarr
declare -a newarr = ([8] = "1234")