Was der Titel schon sagt: was es in eine Variable zu verkapseln bedeutet {}
, ""
oder "{}
?“Ich habe nicht in der Lage gewesen , irgendwelche Erklärungen Online über diese zu finden - ich habe nicht in der Lage gewesen, sie zu beziehen , außer daß die Symbole verwenden, die gibt nichts nach.
Hier ist ein Beispiel:
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")
Dies:
for group in "${groups[@]}"; do
echo $group
done
Erweist sich als viel anders als dies:
for group in $groups; do
echo $group
done
und das:
for group in ${groups}; do
echo $group
done
Nur der erste erreicht das, was ich will: jedes Element im Array durchlaufen. Ich bin nicht wirklich klar auf die Unterschiede zwischen $groups
, "$groups"
, ${groups}
und "${groups}"
. Wenn jemand es erklären könnte, würde ich es schätzen.
Als zusätzliche Frage: Kennt jemand die akzeptierte Art, auf diese Kapselungen zu verweisen?
bash
Skript.Antworten:
Zahnspange (
$var
vs.${var}
)In den meisten Fällen
$var
und${var}
sind die gleichen:Die geschweiften Klammern werden nur benötigt, um Mehrdeutigkeiten in Ausdrücken aufzulösen:
Zitate (
$var
vs."$var"
vs."${var}"
)Wenn Sie eine Variable in doppelte Anführungszeichen setzen, weisen Sie die Shell an, sie als einzelnes Wort zu behandeln, auch wenn sie Leerzeichen enthält:
Vergleichen Sie dieses Verhalten mit Folgendem:
Wie bei
$var
vs.${var}
werden die Klammern nur zur Begriffsklärung benötigt, zum Beispiel:Beachten Sie, dass
"${var}bar"
im zweiten Beispiel oben auch geschrieben werden könnte"${var}"bar
, in welchem Fall Sie die Klammern nicht mehr benötigen, dh"$var"bar
. Wenn Ihre Zeichenfolge jedoch viele Anführungszeichen enthält, können diese alternativen Formulare schwer lesbar (und daher schwer zu pflegen) sein. Diese Seite bietet eine gute Einführung in das Zitieren in Bash.Arrays (
$var
vs.$var[@]
vs.${var[@]}
)Nun zu Ihrem Array. Laut Bash-Handbuch :
Mit anderen Worten, wenn Sie keinen Index mit angeben
[]
, erhalten Sie das erste Element des Arrays:Welches ist genau das gleiche wie
Um alle Elemente eines Arrays abzurufen, müssen Sie
@
als Index verwenden, z${foo[@]}
. Die geschweiften Klammern sind für Arrays erforderlich, da die Shell ohne sie den$foo
Teil zuerst erweitern würde und das erste Element des Arrays gefolgt von einem Literal ergibt[@]
:Diese Seite ist eine gute Einführung in Arrays in Bash.
Zitate überarbeitet (
${foo[@]}
vs."${foo[@]}"
)Sie haben nicht danach gefragt, aber es ist ein subtiler Unterschied, über den Sie gut Bescheid wissen sollten. Wenn die Elemente in Ihrem Array Leerzeichen enthalten könnten, müssen Sie doppelte Anführungszeichen verwenden, damit jedes Element als separates "Wort" behandelt wird:
Vergleichen Sie dies mit dem Verhalten ohne doppelte Anführungszeichen:
quelle
${var:?}
, der einen Fehler liefert, wenn die Variable nicht gesetzt oder nicht gesetzt ist. REF: github.com/koalaman/shellcheck/wiki/SC2154${parameter:-word}
,${parameter:=word}
,${parameter#word}
,${parameter/pattern/string}
, und so weiter. Ich denke, das würde den Rahmen dieser Antwort sprengen.TL; DR
Alle Beispiele, die Sie geben, sind Variationen von Bash Shell-Erweiterungen . Erweiterungen erfolgen in einer bestimmten Reihenfolge, und einige haben bestimmte Anwendungsfälle.
Klammern als Token-Begrenzer
Die
${var}
Syntax wird hauptsächlich zum Abgrenzen mehrdeutiger Token verwendet. Betrachten Sie beispielsweise Folgendes:Klammern in Array-Erweiterungen
Die geschweiften Klammern sind erforderlich, um auf die Elemente eines Arrays und für andere spezielle Erweiterungen zuzugreifen . Beispielsweise:
Tokenisierung
Die meisten Ihrer restlichen Fragen haben mit dem Zitieren und der Tokenisierung der Eingabe durch die Shell zu tun. Berücksichtigen Sie in den folgenden Beispielen den Unterschied, wie die Shell die Wortteilung durchführt :
Das @Symbol interagiert mit Zitaten anders als *. Speziell:
$@
"[e] x erweitert sich zu den Positionsparametern, beginnend mit eins. Wenn die Erweiterung in doppelten Anführungszeichen erfolgt, wird jeder Parameter zu einem separaten Wort erweitert."${name[*]}
zu einem einzelnen Wort erweitert, wobei der Wert jedes Array-${name[@]}
Elements durch das erste Zeichen der IFS-Variablen getrennt wird, und jedes Namenselement zu einem separaten Wort erweitert."Sie können dies in Aktion wie folgt sehen:
Die Verwendung einer Erweiterung in Anführungszeichen ist sehr wichtig, wenn Variablen auf Werte mit Leerzeichen oder Sonderzeichen verweisen, die möglicherweise verhindern, dass die Shell die beabsichtigte Wortaufteilung durchführt. Weitere Informationen zur Funktionsweise des Zitierens in Bash finden Sie unter Zitieren.
quelle
Sie müssen zwischen Arrays und einfachen Variablen unterscheiden - und in Ihrem Beispiel wird ein Array verwendet.
Für einfache Variablen:
$var
und${var}
sind genau gleichwertig."$var"
und"${var}"
sind genau gleichwertig.Die beiden Paare sind jedoch nicht in allen Fällen zu 100% identisch. Betrachten Sie die folgende Ausgabe:
Ohne die doppelten Anführungszeichen um die Variable geht der interne Abstand verloren und die Erweiterung wird als zwei Argumente für den
printf
Befehl behandelt. Mit den doppelten Anführungszeichen um die Variable bleibt der interne Abstand erhalten und die Erweiterung wird als ein Argument für denprintf
Befehl behandelt.Bei Arrays sind die Regeln ähnlich und unterschiedlich.
groups
es sich um ein Array handelt , das auf das nullte Element des Arrays verweist$groups
oder${groups}
gleichbedeutend mit dem Verweisen${groups[0]}
ist."${groups[@]}"
ist analog zum Referenzieren"$@"
. Es behält den Abstand in den einzelnen Elementen des Arrays bei und gibt eine Liste von Werten zurück, einen Wert pro Element des Arrays.${groups[@]}
ohne doppelte Anführungszeichen wird der Abstand nicht beibehalten und es können mehr Werte eingeführt werden, als Elemente im Array vorhanden sind, wenn einige der Elemente Leerzeichen enthalten.Beispielsweise:
Die Verwendung
*
anstelle von@
führt zu subtil unterschiedlichen Ergebnissen.Siehe auch So durchlaufen Sie die Argumente in einem
bash
Skript .quelle
Der zweite Satz des ersten Absatzes unter Parametererweiterung in
man bash
lautet:Was Ihnen sagt, dass der Name einfach eine geschweifte Klammer ist und der Hauptzweck darin besteht, zu klären, wo der Name beginnt und endet:
Wenn Sie weiter lesen, entdecken Sie,
Testen wir:
Huh. Ordentlich. Ich wusste das ehrlich gesagt nicht, bevor ich das geschrieben habe (ich hatte noch nie mehr als 9 Positionsparameter).
Natürlich benötigen Sie auch geschweifte Klammern, um die leistungsstarken Parametererweiterungsfunktionen wie z
sowie Array-Erweiterung.
quelle
Ein verwandter Fall, der oben nicht behandelt wurde. Das Zitieren einer leeren Variablen scheint die Dinge zu ändern
test -n
. Dies wird speziell als Beispiel iminfo
Text angegebencoreutils
, aber nicht wirklich erklärt:Ich würde gerne die ausführliche Erklärung hören. Mein Test bestätigt dies, und ich bin jetzt meine Variablen für alle String - Tests zu zitieren, um zu vermeiden ,
-z
und-n
das gleiche Ergebnis zurück.quelle
Nun, ich weiß, dass die Kapselung einer Variablen Ihnen hilft, mit etwas zu arbeiten wie:
oder eine solche Syntax, bei der Sie etwas mit Ihrer Variablen tun möchten, bevor Sie den Wert zurückgeben.
Wenn Sie jetzt Ihren Code sehen, ist die ganze Magie in Ihnen
Die Magie ist da drin, weil man nicht einfach schreiben kann:
$groups[@]
Sie setzen Ihre Variable in das,
{}
weil Sie Sonderzeichen[]
und verwenden möchten@
. Sie können Ihre Variable nicht einfach benennen oder aufrufen:@
odersomething[]
weil dies reservierte Zeichen für andere Operationen und Namen sind.quelle