Я прочитал в примечаниях к выпуску Bash 5.1 эти интересные вещи:
я. Преобразование переменной `@a' теперь печатает атрибуты для неустановленных переменных массива.
аа. Преобразование переменной `@A' теперь печатает команду объявления, которая устанавливает атрибуты переменной, если переменная имеет атрибуты, но не установлена.
Итак, давайте проверим, как они работают. Во-первых, с Bash 4.3, чтобы увидеть прогресс и увидеть, что раньше они производили то же самое:
$ declare -A arra=([k1] = "v1" [k2] = "v2" [k3] = "")
$ echo "${arra[@]@a}"
v1 v2
$ echo "${arra[@]@A}"
v1 v2
Теперь с Bash 5.1, используя последовательность чередующихся клавиш:
$ declare -A arra=(k1 v2 k2 v2 k3)
$ echo "${arra[@]@a}"
A A A
$ echo "${arra[@]@A}"
declare -A arra=([k1] = "v1" [k2] = "v2" [k3] = "" )
Таким образом, @A
полезно увидеть определение массива, тогда как @a
дает «A» для каждого ассоциативного значения. Имеет ли это?
Проверка Справочного руководства по Bash 5.1 → раздел Массивы говорит:
${parameter@operator}
а
Расширение представляет собой строку, состоящую из значений флагов, представляющих атрибуты параметра.
Но я не вижу, что еще, кроме формы «А», может быть выходом. Если я использую его против обычной переменной, он ничего не производит:
$ v=1 $ echo "${v@a}" # nothing $ v = "hello" $ echo "${v@a}" # nothing
и собственно для всех флагов (кроме -n
): for f in a A i l n r t u x; do (declare -$f v; echo "$f: ${v@a}"); done
. Для ссылки на переменную @a
покажет флаг цели: declare -i a=1; declare -n v=a; echo "${v@a}"
.
@gniourf_gniourf о, интересно. Таким образом, у нас может быть "A" для ассоциативного массива, "i" для целого числа, "il" для...?, "a" для массива и "x" для...
Да, il
интересно :)
. Флаги будут комбинироваться интересным (и непоследовательным) образом (запустите команду, которую я дал в предыдущем комментарии, без подоболочки для declare
).
@gniourf_gniourf очень мило! Некоторые из них не работают вместе, если я использую for f in a A i l n r t u x; do declare -$f v; echo "$f: ${v@a}"; done
, и мне также выдается сообщение об ошибке «bash: declare: `1': неверное имя переменной для ссылки на имя». В любом случае, то, что вы прокомментировали, - это неплохая информация, которая считается отличным ответом :)
Вы увидите другие флаги, кроме A
, когда переменные были отмечены declare
этими флагами:
$ declare -i v
$ echo "${v@a}"
i
$
declare
знает об этих флагах: a
, A
, i
, l
, n
, r
, t
, u
и x
(описания см. в help declare
). Вот небольшой фрагмент, чтобы увидеть это в действии (сделано в новом сеансе или unset v
раньше):
$ unset v
$ for f in a A i l n r t u x; do (declare -$f v; echo "$f: ${v@a}"); done
a: a
A: A
i: i
l: l
n:
r: r
t: t
u: u
x: x
$
Что-то происходит с -n
(отсылка). В этом случае Bash вернет флаг цели:
$ declare -i a
$ declare -n v=a
$ echo "${v@a}"
i
$
Как замечено в комментариях ОП, флаги могут сочетаться странным и непоследовательным образом:
$ # declaring integer AND lowercase
$ declare -il v
$ echo "${v@a}"
il
$ # ???
И просто для удовольствия: удаление подоболочки для declare
(чтобы флаги объединялись) в предыдущем фрагменте:
$ unset v
$ for f in a A i l n r t u x; do declare -$f v; echo "$f: ${v@a}"; done
a: a
bash: declare: v: cannot convert indexed to associative array
A: a
i: ai
l: ail
bash: declare: v: reference variable cannot be an array
n: ail
r: airl
t: airtl
u: airtu
x: airtxu
$
(Я сделал это только для развлечения, не для того, чтобы показать что-то особенное, кроме некоторых причудливых уголков Bash).
Вы даже можете указать на соответствующее руководство по bash, раздел 3.5.3 Расширение параметров оболочки: ${parameter@operator}
Расширение представляет собой либо преобразование значения параметра, либо информацию о самом параметре, в зависимости от значения оператора. Каждый оператор представляет собой одну букву
вы увидите вывод, отличный от
A
, например,declare -i v=1
илиdeclare -l v = "Hello"
, а также для экспортированных переменных:declare -x v=1
, которые могут иметь свое применение.