O que o título diz: o que significa encapsular uma variável em {}
, ""
ou "{}
"? Não consegui encontrar explicações on-line sobre isso - não consegui me referir a elas, exceto pelo uso dos símbolos, que não produz nada.
Aqui está um exemplo:
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")
Este:
for group in "${groups[@]}"; do
echo $group
done
Prova ser muito diferente disso:
for group in $groups; do
echo $group
done
e isto:
for group in ${groups}; do
echo $group
done
Somente o primeiro realiza o que eu quero: iterar através de cada elemento da matriz. Eu não sou muito claro sobre as diferenças entre $groups
, "$groups"
, ${groups}
e "${groups}"
. Se alguém pudesse explicar, eu agradeceria.
Como uma pergunta extra - alguém sabe a maneira aceita de se referir a esses encapsulamentos?
bash
script?Respostas:
Suspensórios (
$var
vs.${var}
)Na maioria dos casos,
$var
e${var}
são os mesmos:Os colchetes são necessários apenas para resolver a ambiguidade nas expressões:
Citações (
$var
vs."$var"
vs."${var}"
)Ao adicionar aspas duplas em torno de uma variável, você diz ao shell para tratá-lo como uma única palavra, mesmo que contenha espaços em branco:
Compare esse comportamento com o seguinte:
Assim como no
$var
vs.${var}
, as chaves são necessárias apenas para desambiguação, por exemplo:Observe que
"${var}bar"
no segundo exemplo acima também pode ser escrito"${var}"bar
; nesse caso, você não precisa mais dos aparelhos, ou seja"$var"bar
. No entanto, se você tiver muitas aspas em sua sequência, esses formulários alternativos podem ser difíceis de ler (e, portanto, difíceis de manter). Esta página fornece uma boa introdução à citação no Bash.Matrizes (
$var
vs.$var[@]
vs.${var[@]}
)Agora para a sua matriz. De acordo com o manual do bash :
Em outras palavras, se você não fornecer um índice
[]
, obterá o primeiro elemento da matriz:Qual é exatamente o mesmo que
Para obter todos os elementos de uma matriz, você precisa usar
@
como índice, por exemplo${foo[@]}
. As chaves são necessárias com matrizes porque, sem elas, o shell expandiria a$foo
peça primeiro, fornecendo o primeiro elemento da matriz seguido de um literal[@]
:Esta página é uma boa introdução às matrizes no Bash.
Citações revisitadas (
${foo[@]}
vs."${foo[@]}"
)Você não perguntou sobre isso, mas é uma diferença sutil que é bom saber. Se os elementos em sua matriz puderem conter espaços em branco, você precisará usar aspas duplas para que cada elemento seja tratado como uma "palavra:" separada.
Compare isso com o comportamento sem aspas duplas:
fonte
${var:?}
que fornecerá erro quando a variável estiver desabilitada ou não definida. REF: github.com/koalaman/shellcheck/wiki/SC2154${parameter:-word}
,${parameter:=word}
,${parameter#word}
,${parameter/pattern/string}
, e assim por diante. Eu acho que esses estão além do escopo desta resposta.TL; DR
Todos os exemplos que você fornece são variações das expansões do Bash Shell . As expansões acontecem em uma ordem específica e algumas têm casos de uso específicos.
Chaves como delimitadores de token
A
${var}
sintaxe é usada principalmente para delimitar tokens ambíguos. Por exemplo, considere o seguinte:Chaves em expansões de matriz
As chaves são necessárias para acessar os elementos de uma matriz e para outras expansões especiais . Por exemplo:
Tokenização
A maioria das outras perguntas tem a ver com citações e como o shell simboliza a entrada. Considere a diferença de como o shell executa a divisão de palavras nos seguintes exemplos:
O @símbolo interage com a citação de maneira diferente de *. Especificamente:
$@
"[e] xpands para os parâmetros posicionais, começando por um. Quando a expansão ocorre entre aspas duplas, cada parâmetro se expande para uma palavra separada."${name[*]}
expande para uma única palavra com o valor de cada membro da matriz separado pelo primeiro caractere da variável IFS e${name[@]}
expande cada elemento do nome para uma palavra separada".Você pode ver isso em ação da seguinte maneira:
O uso de uma expansão citada é muito importante quando variáveis se referem a valores com espaços ou caracteres especiais que podem impedir que o shell seja dividido da maneira que você deseja. Consulte Citação para obter mais informações sobre como funciona a citação no Bash.
fonte
Você precisa distinguir entre matrizes e variáveis simples - e seu exemplo está usando uma matriz.
Para variáveis simples:
$var
e${var}
são exatamente equivalentes."$var"
e"${var}"
são exatamente equivalentes.No entanto, os dois pares não são 100% idênticos em todos os casos. Considere a saída abaixo:
Sem as aspas duplas em torno da variável, o espaçamento interno é perdido e a expansão é tratada como dois argumentos para o
printf
comando. Com aspas duplas em torno da variável, o espaçamento interno é preservado e a expansão é tratada como um argumento para oprintf
comando.Com matrizes, as regras são semelhantes e diferentes.
groups
é uma matriz, referenciando$groups
ou${groups}
é equivalente a referência${groups[0]}
, o elemento zero da matriz."${groups[@]}"
é análogo a referenciar"$@"
; ele preserva o espaçamento nos elementos individuais da matriz e retorna uma lista de valores, um valor por elemento da matriz.${groups[@]}
sem as aspas duplas não preserva o espaçamento e pode introduzir mais valores do que os elementos da matriz, se alguns deles contiverem espaços.Por exemplo:
Usar em
*
vez de@
leva a resultados sutilmente diferentes.Consulte também Como iterar sobre os argumentos em um
bash
script .fonte
A segunda frase do primeiro parágrafo sob expansão de parâmetros no
man bash
diz,O que informa que o nome é simplesmente chavetas e o principal objetivo é esclarecer onde o nome começa e termina:
Se você ler mais, descobrirá:
Vamos testar:
Hã. Arrumado. Sinceramente, eu não sabia disso antes de escrever isso (nunca tive mais de 9 parâmetros posicionais antes).
Obviamente, você também precisa de chaves para fazer os poderosos recursos de expansão de parâmetros, como
bem como expansão de matriz.
fonte
Um caso relacionado não coberto acima. Citar uma variável vazia parece mudar as coisas
test -n
. Isso é dado especificamente como um exemplo noinfo
texto paracoreutils
, mas não é realmente explicado:Eu adoraria ouvir a explicação detalhada. Meus testes confirmam isso, e agora estou citando minhas variáveis para todos os testes de cadeia de caracteres, para evitar ter
-z
e-n
retornar o mesmo resultado.fonte
Bem, eu sei que o encapsulamento de uma variável ajuda você a trabalhar com algo como:
ou sintaxe como essa, na qual você deseja fazer algo com sua variável antes de retornar o valor.
Agora, se você vir seu código, toda a magia está dentro
a mágica está aí porque você não pode escrever apenas:
$groups[@]
Você está colocando sua variável dentro do
{}
porque deseja usar caracteres especiais[]
e@
. Você não pode nomear ou chamar sua variável apenas:@
ousomething[]
porque esses são caracteres reservados para outras operações e nomes.fonte