I. Klammern, runde Klammern ()

1. Einfache Klammern ()

  • BefehlsgruppeDie Befehle innerhalb der Klammern werden nacheinander in einer neuen Subshell ausgeführt, daher können Variablen innerhalb der Klammern nicht vom restlichen Skript verwendet werden. Mehrere Befehle innerhalb der Klammern werden durch Semikolons getrennt; beim letzten Befehl kann das Semikolon weggelassen werden, und zwischen Befehlen und Klammern sind keine Leerzeichen erforderlich.
  • BefehlssubstitutionEntspricht `cmd`. Wenn die Shell die Befehlszeile durchsucht und die Struktur $(cmd) findet, führt sie cmd einmal aus, erhält deren Standardausgabe und setzt diese Ausgabe in den ursprünglichen Befehl ein. Einige Shells unterstützen dies nicht, zum Beispiel tcsh.
  • Wird zum Initialisieren von Arrays verwendetBeispiel: array=(a b c d)

2. Doppelte Klammern (( ))

  • Ganzzahlerweiterung. Diese Erweiterung führt Ganzzahlarithmetik aus und unterstützt keine Gleitkommazahlen. Die Struktur ((exp)) erweitert und wertet den Wert eines arithmetischen Ausdrucks aus. Wenn das Ergebnis des Ausdrucks 0 ist, gibt sie einen Exit-Status von 1 zurück, also "false"; wenn der Ausdruck einen Wert ungleich Null hat, gibt sie Exit-Status 0 zurück, also "true". Wenn sie als logischer Test verwendet wird, ist der Ausdruck exp 1, wenn er wahr ist, und 0, wenn er falsch ist.
  • Solange die Operatoren und Ausdrücke innerhalb der Klammern den Operationsregeln der Sprache C folgen, können sie in $((exp)) verwendet werden, sogar der Ternäroperator. Bei Operationen in verschiedenen Basen (wie binär, oktal, hexadezimal) werden die Ausgabeergebnisse automatisch in Dezimal umgewandelt. Zum Beispiel: echo $((16#5f)) ergibt 95 (hexadezimal zu dezimal).
  • Allein die Verwendung von (( )) kann auch Variablenwerte neu definieren, z. B. a=5; ((a++)) kann $a auf 6 neu definieren.
  • Häufig für arithmetische Vergleiche verwendet. Variablen innerhalb doppelter Klammern benötigen kein $-Präfix. Mehrere Ausdrücke darin werden unterstützt, getrennt durch Kommas. Solange die Ausdrücke innerhalb der Klammern den Regeln der Sprache C entsprechen. Zum Beispiel können Sie direkt for((i=0;i<5;i++)) verwenden; ohne doppelte Klammern wäre es for i in `seq 0 4` oder for i in {0..4}. Ein weiteres Beispiel: Sie können direkt if (($i<5)) verwenden; ohne doppelte Klammern wäre es if [ $i -lt 5 ].

II. Klammern, eckige Klammern []

1. Einzelne eckige Klammern []

  • [ ist ein interner Befehl von bash, und [ und test sind äquivalent. Wenn wir keinen absoluten Pfad angeben, ist der Befehl, den wir normalerweise verwenden, der integrierte Befehl von bash. In der if/test-Struktur ist die linke Klammer das Befehlstoken, das test aufruft, und die rechte Klammer schließt den Bedingungstest ab. Dieser Befehl behandelt seine Argumente als Vergleichsausdruck oder als Dateitest und gibt abhängig vom Vergleichsergebnis einen Exit-Status zurück. Die rechte Klammer ist in der if/test-Struktur nicht unbedingt erforderlich, aber neuere Versionen von Bash verlangen sie.
  • Bei test und [] sind die einzigen verfügbaren Vergleichsoperatoren == und !=; beide werden für den Zeichenkettenvergleich verwendet und können nicht für den Ganzzahlenvergleich benutzt werden. Für den Ganzzahlenvergleich sind nur Formen wie -eq, -gt erlaubt. Weder der Zeichenketten- noch der Ganzzahlenvergleich unterstützt die Größer-als- oder Kleiner-als-Zeichen. Wenn Sie sie wirklich für den Zeichenkettenvergleich verwenden möchten, können Sie die maskierte Form verwenden. Zum Beispiel ist beim Vergleich von "ab" und "bc": [ ab \< bc ] wahr, was bedeutet, dass es Status 0 zurückgibt. Logisches UND und logisches ODER in [ ] werden durch -a und -o dargestellt.
  • Zeichenbereich. Wird als Teil eines regulären Ausdrucks verwendet, um einen passenden Zeichenbereich zu beschreiben. Reguläre Ausdrücke können nicht in eckigen Klammern verwendet werden, wenn diese für Testzwecke genutzt werden.
  • Im Kontext einer Array-Struktur werden eckige Klammern verwendet, um auf den Index jedes Elements im Array zu verweisen.

2. Doppelte eckige Klammern [[ ]]

  • [[ ist ein Schlüsselwort in der Programmiersprache bash. Es ist kein Befehl; das [[ ]]-Konstrukt ist vielseitiger als das [ ]-Konstrukt. Zwischen [[ und ]] findet keine Dateinamenerweiterung oder Wortaufteilung statt, aber Parameterexpansion und Befehlssubstitution finden statt.
  • Es unterstützt Musterabgleich für Zeichenketten; mit dem =~-Operator unterstützt es sogar Shell-reguläre Ausdrücke. Beim Vergleich von Zeichenketten kann die rechte Seite als Muster statt nur als Zeichenkette behandelt werden, z. B. ist [[ hello == hell? ]] wahr. In [[ ]] sind keine Anführungszeichen erforderlich, wenn Zeichenketten oder Platzhalter abgeglichen werden.
  • Die Verwendung des bedingten Testkonstrukts [[ ... ]] anstelle von [ ... ] kann viele Logikfehler in Skripten verhindern. Zum Beispiel funktionieren die Operatoren &&, ||, < und > im [[ ]]-Konstrukt ordnungsgemäß, aber wenn sie in [ ] auftreten, wird ein Fehler gemeldet. Zum Beispiel können Sie direkt if [[ $a != 1 && $a != 2 ]] verwenden; ohne doppelte Klammern wäre es if [ $a -ne 1] && [ $a != 2 ] oder if [ $a -ne 1 -a $a != 2 ].
  • Bash behandelt den Ausdruck innerhalb der doppelten eckigen Klammern als einzelnes Element und gibt einen Exit-Statuscode zurück.
if ($i<5)    
if [ $i -lt 5 ]    
if [ $a -ne 1 -a $a != 2 ]    
if [ $a -ne 1] && [ $a != 2 ]    
if [[ $a != 1 && $a != 2 ]]    
     
for i in $(seq 0 4);do echo $i;done    
for i in `seq 0 4`;do echo $i;done    
for ((i=0;i<5;i++));do echo $i;done    
for i in {0..4};do echo $i;done    

III. Geschweifte Klammern {}

1. Häufige Verwendung

(1) Klammer-Expansion. (Globbing) erweitert Dateinamen innerhalb geschweifter Klammern. Innerhalb geschweifter Klammern ist Leerraum nicht erlaubt, es sei denn, er ist in Anführungszeichen gesetzt oder escaped. Erster Typ: erweitert eine kommagetrennte Liste von Dateien innerhalb geschweifter Klammern, z. B. ergibt touch {a,b}.txt a.txt b.txt. Zweiter Typ: erweitert eine sequenzielle Liste von Dateien, die durch zwei Punkte (..) innerhalb geschweifter Klammern getrennt sind, z. B. ergibt touch {a..d}.txt a.txt b.txt c.txt d.txt

# ls {ex1,ex2}.sh    
ex1.sh  ex2.sh    
# ls {ex{1..3},ex4}.sh    
ex1.sh  ex2.sh  ex3.sh  ex4.sh    
# ls {ex[1-3],ex4}.sh    
ex1.sh  ex2.sh  ex3.sh  ex4.sh    

(2) Codeblock, auch als interne Gruppe bekannt. Diese Struktur erzeugt tatsächlich eine anonyme Funktion. Im Gegensatz zu Befehlen in runden Klammern werden Befehle innerhalb geschweifter Klammern nicht in einer neuen Subshell ausgeführt, sodass der Rest des Skripts weiterhin Variablen innerhalb der geschweiften Klammern verwenden kann. Befehle innerhalb geschweifter Klammern werden durch Semikolons getrennt, und der letzte muss ebenfalls ein Semikolon haben. Zwischen dem ersten Befehl und der linken geschweiften Klammer in {} muss ein Leerzeichen stehen.

2. Einige spezielle Substitutionskonstrukte

${var:-string} 
${var:+string} 
${var:=string}
${var:?string}

1. ${var:-string} und ${var:=string}: Wenn die Variable var leer ist, dann wird string in der Befehlszeile verwendet, um ${var:-string} zu ersetzen; andernfalls, wenn var nicht leer ist, wird der Wert von var verwendet, um ${var:-string} zu ersetzen. Die Substitutionsregel für ${var:=string} ist dieselbe wie für ${var:-string}, außer dass ${var:=string}, wenn var leer ist, es durch string ersetzt und außerdem string an var zuweist. Eine sehr häufige Verwendung von ${var:=string} besteht darin, zu prüfen, ob einer Variablen ein Wert zugewiesen wurde, und falls nicht, ihr einen Standardwert zuzuweisen.

2. Die Substitutionsregel für ${var:+string} ist das Gegenteil der obigen. Das heißt, sie wird nur dann durch string ersetzt, wenn var nicht leer ist; wenn var leer ist, wird sie nicht ersetzt, oder gleichwertig, sie wird durch den Wert von var ersetzt, der leer ist. (Da var an diesem Punkt leer ist, sind die beiden Aussagen äquivalent.)

3. Substitutionsregel für {var:?string}: Wenn die Variable var nicht leer ist, dann wird der Wert von var verwendet, um ${var:?string} zu ersetzen; wenn var leer ist, wird string auf die Standardfehlerausgabe ausgegeben und das Skript beendet. Wir können diese Funktion verwenden, um zu prüfen, ob eine Variable gesetzt wurde.

Ergänzende ExpansionIn den oben genannten fünf Substitutionskonstrukten muss string keine Konstante sein; es kann der Wert einer anderen Variablen oder die Ausgabe eines Befehls sein.

3. Vier Substitutionskonstrukte für den Mustervergleich

Eselsbrücke für den Mustervergleich:

# removes the left side (on the keyboard, # is to the left of $)
% removes the right side (on the keyboard, % is to the right of $)

Ein einzelnes Symbol in # und % ist die kleinste Übereinstimmung, während zwei identische Symbole die größte Übereinstimmung sind.

${var%pattern}
${var%%pattern
${var#pattern}
${var##pattern}
  • Erstes Muster: ${variable%pattern}. Bei diesem Muster durchsucht die Shell variable, um festzustellen, ob es mit dem angegebenen Muster endet. Wenn ja, entfernt sie das kürzeste passende Muster auf der rechten Seite aus dem Inhalt von variable in der Befehlszeile.
  • Zweites Muster: ${variable%%pattern}. Bei diesem Muster durchsucht die Shell variable, um festzustellen, ob es mit dem angegebenen Muster endet. Wenn ja, entfernt sie das längste passende Muster auf der rechten Seite aus dem Inhalt von variable in der Befehlszeile.
  • Drittes Muster: ${variable#pattern}. Bei diesem Muster durchsucht die Shell variable, um festzustellen, ob es mit dem angegebenen Muster beginnt. Wenn ja, entfernt sie das kürzeste passende Muster auf der linken Seite aus dem Inhalt von variable in der Befehlszeile.
  • Viertes Muster: ${variable##pattern}. Bei diesem Muster durchsucht die Shell variable, um festzustellen, ob es mit dem angegebenen Muster endet. Wenn ja, entfernt sie das längste passende Muster auf der rechten Seite aus dem Inhalt von variable in der Befehlszeile.
  • In allen diesen vier Modi wird der Wert von variable niemals geändert. Dabei unterscheiden sich % und %%, # und ## nur, wenn das *-Vergleichssymbol im Muster verwendet wird. Das Muster in der Struktur unterstützt Wildcards: * steht für null oder mehr beliebige Zeichen, ? entspricht genau einem beliebigen Zeichen, [...] entspricht den Zeichen innerhalb der Klammern, und [!...] entspricht nicht den Zeichen innerhalb der Klammern.
# var=testcase    
# echo $var    
testcase    
# echo ${var%s*e}   
testca    
# echo $var    
testcase   
# echo ${var%%s*e}   
te  
# echo ${var#?e}    
stcase  
# echo ${var##?e}    
stcase  
# echo ${var##*e}    
  
# echo ${var##*s}    
e    
# echo ${var##test}    
case    

4. String-Extraktion und -Ersetzung

${var:num}
${var:num1:num2}
${var/pattern/pattern}
${var//pattern/pattern}
  • Erster Modus: ${var:num}. In diesem Modus extrahiert die Shell alle Zeichen vom num-ten Zeichen bis zum Ende von var. Wenn num positiv ist, beginnt die Extraktion an Position 0 von links; wenn num negativ ist, wird die Teilzeichenkette von rechts beginnend extrahiert, aber Sie müssen nach dem Doppelpunkt ein Leerzeichen einfügen, oder eine Zahl verwenden, oder die gesamte num in Klammern setzen, wie ${var: -2}, ${var:1-3} oder ${var:(-2)}.
  • Zweiter Modus: ${var:num1:num2}, wobei num1 die Position und num2 die Länge ist. Das bedeutet, eine Teilzeichenkette der Länge $num2 ab Position $num1 in der Zeichenkette $var zu extrahieren. Negative Zahlen sind nicht erlaubt.
  • Dritter Modus: ${var/pattern/pattern} bedeutet, das erste Vorkommen des in der Zeichenkette var gefundenen Musters durch ein anderes Muster zu ersetzen.
  • Vierter Modus: ${var//pattern/pattern} bedeutet, alle Vorkommen des in der Zeichenkette var gefundenen Musters durch ein anderes Muster zu ersetzen.
[root@centos ~]# var=/home/centos  
[root@centos ~]# echo $var  
/home/centos  
[root@centos ~]# echo ${var:5}  
/centos  
[root@centos ~]# echo ${var: -6}  
centos  
[root@centos ~]# echo ${var:(-6)}  
centos  
[root@centos ~]# echo ${var:1:4}  
home  
[root@centos ~]# echo ${var/o/h}  
/hhme/centos  
[root@centos ~]# echo ${var//o/h}  
/hhme/cenths  

IV. Klammern nach dem $-Symbol

  • (1) ${a} ist der Wert der Variablen a. Die geschweiften Klammern können weggelassen werden, wenn keine Mehrdeutigkeit entsteht.
  • (2) $(cmd) ist eine Befehlsersetzung, die dieselbe Wirkung wie `cmd` hat. Das Ergebnis ist die Ausgabe des Shell-Befehls cmd. Einige Shell-Versionen unterstützen jedoch keine $()-Befehlsersetzung, wie z. B. tcsh.
  • (3) $((expression)) hat dieselbe Wirkung wie `expr expression`. Es berechnet den numerischen Wert des mathematischen Ausdrucks exp. Solange exp den Operationsregeln der Sprache C entspricht, können sogar Ternär-Operatoren und logische Ausdrücke ausgewertet werden.

V. Verwendung

  • 1. Ausführen mehrerer Befehle

    • (1) Einfache Klammern, (cmd1;cmd2;cmd3): Startet eine neue Subshell, um die Befehle cmd1, cmd2, cmd3 nacheinander auszuführen, getrennt durch Semikolons. Der letzte Befehl benötigt kein abschließendes Semikolon.
    • (2) Einfache geschweifte Klammern, { cmd1;cmd2;cmd3; }: Führt die Befehle cmd1, cmd2, cmd3 sequenziell in der aktuellen Shell aus, getrennt durch Semikolons. Auf den letzten Befehl muss ein Semikolon folgen, und zwischen dem ersten Befehl und der linken geschweiften Klammer muss ein Leerzeichen stehen.

    Paar{}und()In dieser Hinsicht wirkt sich ein Umleitungsoperator innerhalb der Klammern nur auf diesen einzelnen Befehl aus, während ein Umleitungsoperator außerhalb der Klammern alle Befehle in den Klammern beeinflusst.

    Originalquelle: http://blog.csdn.net/taiyang1987912/article/details/39551385