О чем говорится в названии: что означает инкапсулировать переменную в {}
, ""
или "{}
"? Я не смог найти никаких объяснений в Интернете по этому поводу - я не мог ссылаться на них, за исключением использования символов, которые ничего не дает.
Вот пример:
declare -a groups
groups+=("CN=exampleexample,OU=exampleexample,OU=exampleexample,DC=example,DC=com")
groups+=("CN=example example,OU=example example,OU=example example,DC=example,DC=com")
Это:
for group in "${groups[@]}"; do
echo $group
done
Оказывается, сильно отличается от этого:
for group in $groups; do
echo $group
done
и это:
for group in ${groups}; do
echo $group
done
Только первый выполняет то, что я хочу: перебирать каждый элемент в массиве. Я не совсем ясно , о различиях между $groups
, "$groups"
, ${groups}
и "${groups}"
. Если бы кто-нибудь мог это объяснить, я был бы признателен.
В качестве дополнительного вопроса - знает ли кто-нибудь общепринятый способ обращения к этим инкапсуляциям?
bash
скрипте?Ответы:
Подтяжки (
$var
vs.${var}
)В большинстве случаев,
$var
и${var}
то же самое:Скобки нужны только для устранения двусмысленности в выражениях:
Котировки (
$var
против"$var"
против"${var}"
)Когда вы добавляете двойные кавычки вокруг переменной, вы указываете оболочке рассматривать ее как одно слово, даже если оно содержит пробелы:
Сравните это поведение со следующим:
Как и в случае с
$var
vs.${var}
, фигурные скобки нужны только для устранения неоднозначности, например:Обратите внимание , что
"${var}bar"
во втором примере выше , также может быть написано"${var}"bar
, в этом случае вам не нужны брекеты больше, то есть"$var"bar
. Однако, если у вас много кавычек в вашей строке, эти альтернативные формы могут быть трудно читать (и, следовательно, их трудно поддерживать). Эта страница представляет собой хорошее введение в цитирование в Bash.Массивы (
$var
против$var[@]
против${var[@]}
)Теперь о вашем массиве. Согласно руководству по bash :
Другими словами, если вы не укажете индекс
[]
, вы получите первый элемент массива:Это точно так же, как
Чтобы получить все элементы массива, вам нужно использовать
@
в качестве индекса, например${foo[@]}
. Фигурные скобки требуются с массивами, потому что без них оболочка$foo
сначала расширила бы часть, предоставив первый элемент массива, за которым следует литерал[@]
:Эта страница - хорошее введение в массивы в Bash.
Повторение цитат (
${foo[@]}
vs."${foo[@]}"
)Вы не спрашивали об этом, но это тонкая разница, о которой полезно знать. Если элементы в вашем массиве могут содержать пробелы, вам нужно использовать двойные кавычки, чтобы каждый элемент обрабатывался как отдельное «слово»:
Сравните это с поведением без двойных кавычек:
источник
${var:?}
который выдаст ошибку, если переменная не установлена или не установлена. ССЫЛКА: github.com/koalaman/shellcheck/wiki/SC2154${parameter:-word}
,${parameter:=word}
,${parameter#word}
,${parameter/pattern/string}
, и так далее. Я думаю, что это выходит за рамки этого ответа.TL; DR
Все приведенные вами примеры являются вариациями расширений оболочки Bash . Расширения происходят в определенном порядке, и у некоторых есть определенные варианты использования.
Фигурные скобки как разделители токенов
${var}
Синтаксис в основном используются для ограничивающих неоднозначные маркеров. Например, рассмотрите следующее:Фигурные скобки в расширениях массивов
Фигурные скобки необходимы для доступа к элементам массива и для других специальных расширений . Например:
лексемизацию
Большинство остальных вопросов связаны с цитированием и тем, как оболочка токенизирует ввод. Рассмотрим разницу в том, как оболочка выполняет разбиение слов в следующих примерах:
@Символ взаимодействует с экранированием иначе , чем *. В частности:
$@
«[e] расширяется до позиционных параметров, начиная с единицы. Когда раскрытие происходит в двойных кавычках, каждый параметр заменяется отдельным словом».${name[*]}
заменяется одним словом со значением каждого члена массива, разделенным первым символом переменной IFS, и${name[@]}
расширяет каждый элемент имени до отдельного слова».Вы можете увидеть это в действии следующим образом:
Использование расширения в кавычках имеет большое значение, когда переменные ссылаются на значения с пробелами или специальными символами, которые могут помешать оболочке разбивать слова так, как вы намереваетесь. См. Цитирование для получения дополнительной информации о том, как работает цитирование в Bash.
источник
Вам нужно различать массивы и простые переменные - и в вашем примере используется массив.
Для простых переменных:
$var
и${var}
в точности эквивалентны."$var"
и"${var}"
в точности эквивалентны.Однако эти две пары не во всех случаях идентичны на 100%. Рассмотрим вывод ниже:
Если переменная не заключена в двойные кавычки, внутренний интервал теряется, а раскрытие рассматривается как два аргумента
printf
команды. Если переменная заключена в двойные кавычки, внутренний интервал сохраняется, а расширение рассматривается как один аргументprintf
команды.С массивами правила одинаковы и разные.
groups
- массив, ссылка на нулевой элемент массива$groups
или${groups}
равносильна ссылке${groups[0]}
на него."${groups[@]}"
аналогична ссылке"$@"
; он сохраняет интервалы в отдельных элементах массива и возвращает список значений, по одному значению на элемент массива.${groups[@]}
без двойных кавычек не сохраняет интервал и может вводить больше значений, чем имеется элементов в массиве, если некоторые из элементов содержат пробелы.Например:
Использование
*
вместо@
приводит к несколько другим результатам.См. Также Как перебирать аргументы в
bash
скрипте .источник
Второе предложение первого абзаца в разделе « Расширение параметров в»
man bash
гласит:Это говорит о том, что имя состоит только из фигурных скобок , и основная цель - уточнить, где имя начинается и заканчивается:
Если вы прочтете дальше, вы обнаружите,
Проверим:
Да. Ухоженная. Я, честно говоря, не знал этого до того, как написал это (у меня никогда раньше не было более 9 позиционных параметров).
Конечно, фигурные скобки также необходимы для использования мощных функций расширения параметров, таких как
а также расширение массива.
источник
Связанный случай, не описанный выше. Цитирование пустой переменной, похоже, меняет положение
test -n
. Это специально дается в качестве примера вinfo
текстеcoreutils
, но не объясняется на самом деле:Я хотел бы услышать подробное объяснение. Мое тестирование подтверждает это, и теперь я цитирую свои переменные для всех строковых тестов, чтобы избежать получения одного
-z
и-n
того же результата.источник
Что ж, я знаю, что инкапсуляция переменной помогает вам работать с чем-то вроде:
или подобный синтаксис, когда вы хотите что-то сделать с вашей переменной перед возвратом значения.
Теперь, если вы видите свой код, вся магия внутри
магия здесь, потому что вы не можете написать просто:
$groups[@]
Вы помещаете свою переменную внутрь,
{}
потому что хотите использовать специальные символы[]
и@
. Вы не можете назвать или назвать свою переменную просто:@
илиsomething[]
потому что это зарезервированные символы для других операций и имен.источник