Ich bin verwirrt über die Verwendung von Klammern, Klammern, geschweiften Klammern in Bash sowie den Unterschied zwischen ihren Doppel- oder Einzelformen. Gibt es eine klare Erklärung?
In Bash test
und [
sind Shell Builtins.
Die doppelte Klammer , bei der es sich um ein Shell-Schlüsselwort handelt, ermöglicht zusätzliche Funktionen. Beispielsweise können Sie &&
und ||
anstelle von -a
und verwenden, -o
und es gibt einen Operator für die Übereinstimmung regulärer Ausdrücke =~
.
In einem einfachen Test scheinen doppelte eckige Klammern viel schneller zu bewerten als einzelne.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Die geschweiften Klammern werden zusätzlich zur Begrenzung eines Variablennamens für die Parametererweiterung verwendet, damit Sie Folgendes tun können:
Schneiden Sie den Inhalt einer Variablen ab
$ var="abcde"; echo ${var%d*}
abc
Nehmen Sie ähnliche Ersetzungen vor wie sed
$ var="abcde"; echo ${var/de/12}
abc12
Verwenden Sie einen Standardwert
$ default="hello"; unset var; echo ${var:-$default}
hello
und einige mehr
Durch Klammererweiterungen werden außerdem Listen mit Zeichenfolgen erstellt, die normalerweise in Schleifen durchlaufen werden:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Beachten Sie, dass die führenden Null- und Inkrementfunktionen vor Bash 4 nicht verfügbar waren.
Vielen Dank an gboffi, der mich an Klammererweiterungen erinnert hat.
Doppelte Klammern werden für arithmetische Operationen verwendet :
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
Mit ihnen können Sie die Dollarzeichen für Ganzzahl- und Arrayvariablen weglassen und zur besseren Lesbarkeit Leerzeichen um Operatoren einfügen.
Einzelne Klammern werden auch für Array- Indizes verwendet:
array[4]="hello"
element=${array[index]}
Für (die meisten / alle?) Array-Referenzen auf der rechten Seite ist eine geschweifte Klammer erforderlich.
Der Kommentar von Ephemient erinnerte mich daran, dass Klammern auch für Unterschalen verwendet werden. Und dass sie verwendet werden, um Arrays zu erstellen.
array=(1 2 3)
echo ${array[1]}
2
:
.$[expression]
; Dies ist die alte, veraltete arithmetische Ausdruckssyntax für die neuere, bevorzugte Syntax:$((expression))
bash
ist das Erstellen von Sequenzen, wie unten peripher erwähnt ( stackoverflow.com/a/8552128/2749397 ). Da ich diese Funktion etwas kommentieren möchte (wie Sie es nicht erwähnt haben ;-) I ' Ich nehme mir die Freiheit, die am häufigsten gewählte Antwort als Vehikel zu verwenden ... Zwei Beispiele für Sequenzliterale:echo {01..12}
->01 02 03 04 05 06 07 08 09 10 11 12
(beachten Sie die anfängliche Null);echo {C..Q}
->C D E F G H I J K L M N O P Q
. Seine Hauptverwendung ist in Schleifen, zBfor cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}
-> "01 03 05 07 09 11". Danke für die Erinnerung an Sequenzen. Ich werde es meiner Antwort hinzufügen.Eine einzelne Klammer (
[
) ruft normalerweise ein Programm mit dem Namen auf[
.man test
oderman [
für weitere Infos. Beispiel:Die doppelte Klammer (
[[
) macht (im Grunde) dasselbe wie eine einzelne Klammer, ist jedoch eine eingebaute Bash.Klammern (
()
) werden verwendet, um eine Unterschale zu erstellen. Zum Beispiel:Wie Sie sehen können, konnten Sie mit der Subshell Vorgänge ausführen, ohne die Umgebung der aktuellen Shell zu beeinträchtigen.
(a) Klammern (
{}
) werden verwendet, um Variablen eindeutig zu identifizieren. Beispiel:(b) Klammern werden auch verwendet, um eine Folge von Befehlen im aktuellen Shell-Kontext auszuführen , z
Es gibt jedoch einen subtilen syntaktischen Unterschied zu
( )
(siehe Bash-Referenz ); im Wesentlichen, ein Semikolon;
nach dem letzten Befehl in Klammern ist ein Muss, und die Streben{
,}
müssen durch Leerzeichen umgeben sein.quelle
[
ist eigentlich ein eingebautes in Bash, aber es soll sich/bin/[
im Gegensatz zum[[
eingebauten verhalten.[[
hat verschiedene Funktionen, wie logischere Operationen und verschiedene Anführungszeichenrollen. Zusätzlich: Einzelne Klammern werden auch für Arrays, Prozesssubstitution und erweiterte Globs verwendet. Doppelklammern werden für die Arithmetik verwendet; Geschweifte Klammern{}
werden für die Befehlsgruppierung oder eine Vielzahl von Arten der Parametererweiterung oder Klammererweiterung oder Sequenzerweiterung verwendet. Ich bin sicher, ich habe auch einige andere Anwendungen verpasst ...if [ $VARIABLE == abcdef ]
ist ein Bashismus, der - obwohl er funktioniert - wahrscheinlich vermieden werden sollte; Verwenden Sie entweder explizit bash (if [[ ...==...]]
) oder machen Sie deutlich, dass Sie die traditionellere Bedingung (if [ "$VARIABLE" = "abcdef" ]
) verwenden. Wahrscheinlich sollten Skripte so einfach und portabel wie möglich beginnen, bis sie wirklich spezifische Funktionen für Bash benötigen (aus dem einen oder anderen Grund). Aber auf jeden Fall sollte die Absicht klar sein; "=" und "==" und "[[" und "[" funktionieren unterschiedlich und ihre Verwendung sollte konsistent sein.[ "$var" = ".."]
statt zu testen==
, während sie in C anstelle von Tests zugewiesen wird (und eine häufige Ursache für Fehler ist) ... warum nicht nichttest
verwenden==
statt=
? weiß jemand?/usr/bin/[
kein Symlink zu dem ist/usr/bin/test
, und mehr noch: Diese Programme haben sogar ein paar verschiedene Größen!)
ist Teil dercase
Anweisungssyntax zum Beenden einer Fallzeile. Es hat keine öffnende Klammer. Das warf mich vom ersten Mal ab, als ich es sah.Klammern
[1] http://wiki.bash-hackers.org/scripting/obsolete
Geschweifte Klammern
Klammern
Doppelte Klammern
quelle
$(varname)
hat nichts mit der Bash-Syntax zu tun . Es ist Teil der Makefile-Syntax .$(varname)
hat in Ihrem Fall keine Beziehung zur Bash-Syntax.Ich wollte nur diese von TLDP hinzufügen :
quelle
echo ${#ARRAY}
drei angezeigt werden, weil das erste Element vonARRAY
drei Zeichen enthält, nicht weil es drei Elemente enthält! Verwenden Sie zum Drucken der Anzahl der Elementeecho ${#ARRAY[@]}
.${TEST:-test}
gleich,$TEST
wenn die VariableTEST
existiert, andernfalls wird einfach die Zeichenfolge "test" zurückgegeben. Es gibt eine andere Version, die noch mehr kann:${TEST:=test}
--- was auch gleich ist,$TEST
wenn TEST existiert, aber wenn dies nicht der Fall ist, erstellt sie die VariableTEST
und weist einen Wert "test" zu und wird auch zum Wert des gesamten Ausdrucks.Der Unterschied zwischen Test , [ und [[ in großen Details in der erklärt BashFAQ .
Und das Fazit:
quelle
Klammern in der Funktionsdefinition
()
Bei der Funktionsdefinition werden Klammern verwendet:Aus diesem Grund müssen Sie auch in Befehlsparametern Klammern vermeiden:
quelle
unset -f echo
. Siehehelp unset
.quelle