Ce que le titre dit: qu'est-ce que cela signifie pour encapsuler une variable {}
, ""
ou "{}
? » Je ne l' ai pas été en mesure de trouver des explications en ligne à ce sujet - je ne l' ai pas été en mesure de se référer à eux , sauf pour l' utilisation des symboles, ne donne rien.
Voici un exemple:
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")
Ce:
for group in "${groups[@]}"; do
echo $group
done
Se révèle très différent de celui-ci:
for group in $groups; do
echo $group
done
et ça:
for group in ${groups}; do
echo $group
done
Seul le premier accomplit ce que je veux: parcourir chaque élément du tableau. Je ne suis pas vraiment clair sur les différences entre $groups
, "$groups"
, ${groups}
et "${groups}"
. Si quelqu'un pouvait l'expliquer, je l'apprécierais.
Comme question supplémentaire - est-ce que quelqu'un connaît la manière acceptée de se référer à ces encapsulations?
bash
script?Réponses:
Bretelles (
$var
vs.${var}
)Dans la plupart des cas,
$var
et${var}
sont les mêmes:Les accolades ne sont nécessaires que pour résoudre l'ambiguïté dans les expressions:
Citations (
$var
vs."$var"
vs."${var}"
)Lorsque vous ajoutez des guillemets doubles autour d'une variable, vous dites au shell de la traiter comme un seul mot, même si elle contient des espaces:
Comparez ce comportement avec ce qui suit:
Comme avec
$var
vs.${var}
, les accolades ne sont nécessaires que pour lever l'ambiguïté, par exemple:Notez que
"${var}bar"
dans le deuxième exemple ci-dessus pourrait également être écrit"${var}"bar
, auquel cas vous n'avez plus besoin des accolades, c'est-à-dire"$var"bar
. Cependant, si vous avez beaucoup de guillemets dans votre chaîne, ces formes alternatives peuvent devenir difficiles à lire (et donc à maintenir). Cette page fournit une bonne introduction à la citation dans Bash.Tableaux (
$var
vs.$var[@]
vs.${var[@]}
)Maintenant pour votre tableau. Selon le manuel bash :
En d'autres termes, si vous ne fournissez pas d'index avec
[]
, vous obtenez le premier élément du tableau:Ce qui est exactement le même que
Pour obtenir tous les éléments d'un tableau, vous devez utiliser
@
comme index, par exemple${foo[@]}
. Les accolades sont obligatoires avec les tableaux car sans eux, le shell développerait d'abord la$foo
partie, donnant le premier élément du tableau suivi d'un littéral[@]
:Cette page est une bonne introduction aux tableaux dans Bash.
Citations revisitées (
${foo[@]}
vs."${foo[@]}"
)Vous n'avez pas posé de questions à ce sujet, mais c'est une différence subtile qu'il est bon de connaître. Si les éléments de votre tableau peuvent contenir des espaces, vous devez utiliser des guillemets doubles pour que chaque élément soit traité comme un «mot» distinct:
Comparez cela avec le comportement sans guillemets doubles:
la source
${var:?}
qui fournira une erreur lorsque la variable n'est pas définie ou n'est pas définie. REF: github.com/koalaman/shellcheck/wiki/SC2154${parameter:-word}
,${parameter:=word}
,${parameter#word}
,${parameter/pattern/string}
et ainsi de suite. Je pense que cela dépasse le cadre de cette réponse.TL; DR
Tous les exemples que vous donnez sont des variantes des extensions Bash Shell . Les extensions se produisent dans un ordre particulier et certaines ont des cas d'utilisation spécifiques.
Accolades en tant que délimiteurs de jetons
La
${var}
syntaxe est principalement utilisée pour délimiter les jetons ambigus. Par exemple, considérez ce qui suit:Accolades dans les extensions de tableau
Les accolades sont nécessaires pour accéder aux éléments d'un tableau et pour d'autres extensions spéciales . Par exemple:
Tokenisation
La plupart de vos autres questions concernent la citation et la manière dont le shell tokenise l'entrée. Considérez la différence dans la façon dont le shell effectue la division des mots dans les exemples suivants:
Le @symbole interagit avec la citation différemment de *. Plus précisément:
$@
"[e] xpands aux paramètres de position, en commençant par un. Lorsque le développement se produit entre guillemets, chaque paramètre se développe en un mot séparé."${name[*]}
développe en un seul mot avec la valeur de chaque membre du tableau séparé par le premier caractère de la variable IFS, et${name[@]}
développe chaque élément du nom en un mot séparé."Vous pouvez voir cela en action comme suit:
L'utilisation d'un développement entre guillemets est très importante lorsque les variables font référence à des valeurs avec des espaces ou des caractères spéciaux qui pourraient empêcher le shell de diviser les mots comme vous le souhaitez. Voir Citations pour plus d'informations sur le fonctionnement des citations dans Bash.
la source
Vous devez faire la distinction entre les tableaux et les variables simples - et votre exemple utilise un tableau.
Pour les variables simples:
$var
et${var}
sont exactement équivalents."$var"
et"${var}"
sont exactement équivalents.Cependant, les deux paires ne sont pas identiques à 100% dans tous les cas. Considérez la sortie ci-dessous:
Sans les guillemets doubles autour de la variable, l'espacement interne est perdu et le développement est traité comme deux arguments de la
printf
commande. Avec les guillemets doubles autour de la variable, l'espacement interne est conservé et le développement est traité comme un argument de laprintf
commande.Avec les tableaux, les règles sont à la fois similaires et différentes.
groups
est un tableau, référençant$groups
ou${groups}
équivaut à référencer${groups[0]}
, l'élément zéro du tableau."${groups[@]}"
est analogue au référencement"$@"
; il préserve l'espacement entre les éléments individuels du tableau et renvoie une liste de valeurs, une valeur par élément du tableau.${groups[@]}
sans les guillemets doubles ne préserve pas l'espacement et peut introduire plus de valeurs qu'il n'y a d'éléments dans le tableau si certains des éléments contiennent des espaces.Par exemple:
Utiliser
*
au lieu de@
conduit à des résultats subtilement différents.Voir aussi Comment parcourir les arguments d'un
bash
script .la source
La deuxième phrase du premier paragraphe sous extension paramètre en
man bash
dit,Ce qui vous indique que le nom est simplement des accolades , et que le but principal est de clarifier où le nom commence et se termine:
Si vous lisez plus loin vous découvrez,
Testons:
Huh. Soigné. Honnêtement, je ne le savais pas avant d'écrire ceci (je n'avais jamais eu plus de 9 paramètres de position auparavant.)
Bien sûr, vous avez également besoin d'accolades pour faire les puissantes fonctionnalités d'extension de paramètres telles que
ainsi que l'extension de la baie.
la source
Un cas connexe non couvert ci-dessus. Citant une variable vide semble changer les choses pour
test -n
. Ceci est spécifiquement donné à titre d'exemple dans leinfo
texte pourcoreutils
, mais pas vraiment expliqué:J'adorerais entendre l'explication détaillée. Mes tests le confirment, et je cite maintenant mes variables pour tous les tests de chaînes, pour éviter d'avoir
-z
et-n
renvoyer le même résultat.la source
Eh bien, je sais que l'encapsulation d'une variable vous aide à travailler avec quelque chose comme:
ou une syntaxe comme celle-là, où vous voulez faire quelque chose avec votre variable avant de renvoyer la valeur.
Maintenant, si vous voyez votre code, toute la magie est à l'intérieur
la magie est là parce que vous ne pouvez pas écrire simplement:
$groups[@]
Vous placez votre variable dans le
{}
parce que vous souhaitez utiliser des caractères spéciaux[]
et@
. Vous ne pouvez pas nommer ou appeler votre variable simplement:@
ousomething[]
parce que ce sont des caractères réservés pour d'autres opérations et noms.la source