Antworten:
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, zB for 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
oder man [
für weitere Infos. Beispiel:
$ VARIABLE=abcdef
$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
yes
Die doppelte Klammer ( [[
) macht (im Grunde) dasselbe wie eine einzelne Klammer, ist jedoch eine eingebaute Bash.
$ VARIABLE=abcdef
$ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
no
Klammern ( ()
) werden verwendet, um eine Unterschale zu erstellen. Zum Beispiel:
$ pwd
/home/user
$ (cd /tmp; pwd)
/tmp
$ pwd
/home/user
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:
$ VARIABLE=abcdef
$ echo Variable: $VARIABLE
Variable: abcdef
$ echo Variable: $VARIABLE123456
Variable:
$ echo Variable: ${VARIABLE}123456
Variable: abcdef123456
(b) Klammern werden auch verwendet, um eine Folge von Befehlen im aktuellen Shell-Kontext auszuführen , z
$ { date; top -b -n1 | head ; } >logfile
# 'date' and 'top' output are concatenated,
# could be useful sometimes to hunt for a top loader )
$ { date; make 2>&1; date; } | tee logfile
# now we can calculate the duration of a build from the logfile
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.
[
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 nicht test
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 der case
Anweisungssyntax zum Beenden einer Fallzeile. Es hat keine öffnende Klammer. Das warf mich vom ersten Mal ab, als ich es sah.
Klammern
if [ CONDITION ] Test construct
if [[ CONDITION ]] Extended test construct
Array[1]=element1 Array initialization
[a-z] Range of characters within a Regular Expression
$[ expression ] A non-standard & obsolete version of $(( expression )) [1]
[1] http://wiki.bash-hackers.org/scripting/obsolete
Geschweifte Klammern
${variable} Parameter substitution
${!variable} Indirect variable reference
{ command1; command2; . . . commandN; } Block of code
{string1,string2,string3,...} Brace expansion
{a..z} Extended brace expansion
{} Text replacement, after find and xargs
Klammern
( command1; command2 ) Command group executed within a subshell
Array=(element1 element2 element3) Array initialization
result=$(COMMAND) Command substitution, new style
>(COMMAND) Process substitution
<(COMMAND) Process substitution
Doppelte Klammern
(( var = 78 )) Integer arithmetic
var=$(( 20 + 5 )) Integer arithmetic, with variable assignment
(( var++ )) C-style variable increment
(( var-- )) C-style variable decrement
(( var0 = var1<98?9:21 )) C-style ternary operation
$(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 :
~:$ echo $SHELL
/bin/bash
~:$ echo ${#SHELL}
9
~:$ ARRAY=(one two three)
~:$ echo ${#ARRAY}
3
~:$ echo ${TEST:-test}
test
~:$ echo $TEST
~:$ export TEST=a_string
~:$ echo ${TEST:-test}
a_string
~:$ echo ${TEST2:-$TEST}
a_string
~:$ echo $TEST2
~:$ echo ${TEST2:=$TEST}
a_string
~:$ echo $TEST2
a_string
~:$ export STRING="thisisaverylongname"
~:$ echo ${STRING:4}
isaverylongname
~:$ echo ${STRING:6:5}
avery
~:$ echo ${ARRAY[*]}
one two one three one four
~:$ echo ${ARRAY[*]#one}
two three four
~:$ echo ${ARRAY[*]#t}
one wo one hree one four
~:$ echo ${ARRAY[*]#t*}
one wo one hree one four
~:$ echo ${ARRAY[*]##t*}
one one one four
~:$ echo $STRING
thisisaverylongname
~:$ echo ${STRING%name}
thisisaverylong
~:$ echo ${STRING/name/string}
thisisaverylongstring
echo ${#ARRAY}
drei angezeigt werden, weil das erste Element von ARRAY
drei Zeichen enthält, nicht weil es drei Elemente enthält! Verwenden Sie zum Drucken der Anzahl der Elemente echo ${#ARRAY[@]}
.
${TEST:-test}
gleich, $TEST
wenn die Variable TEST
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 Variable TEST
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 .
Um es kurz zu machen: test implementiert die alte, portable Syntax des Befehls. In fast allen Schalen (die ältesten Bourne-Schalen sind die Ausnahme) ist [ein Synonym für Test (erfordert jedoch ein letztes Argument von]). Obwohl alle modernen Shells integrierte Implementierungen von [haben, gibt es normalerweise immer noch eine externe ausführbare Datei mit diesem Namen, z. B. / bin / [.
[[ist eine neue verbesserte Version davon, bei der es sich um ein Schlüsselwort und nicht um ein Programm handelt. Dies hat vorteilhafte Auswirkungen auf die Benutzerfreundlichkeit, wie unten gezeigt. [[wird von KornShell und BASH (z. B. 2.03) verstanden, nicht jedoch von der älteren POSIX oder BourneShell.
Und das Fazit:
Wann sollte der neue Testbefehl verwendet werden [[und wann der alte [? Wenn die Portabilität auf die BourneShell ein Problem darstellt, sollte die alte Syntax verwendet werden. Wenn das Skript andererseits BASH oder KornShell erfordert, ist die neue Syntax viel flexibler.
()
Bei der Funktionsdefinition werden
Klammern verwendet:
function_name () { command1 ; command2 ; }
Aus diesem Grund müssen Sie auch in Befehlsparametern Klammern vermeiden:
$ echo (
bash: syntax error near unexpected token `newline'
$ echo \(
(
$ echo () { command echo The command echo was redefined. ; }
$ echo anything
The command echo was redefined.
unset -f echo
. Siehe help unset
.
Truncate the contents of a variable
$ var="abcde"; echo ${var%d*}
abc
Make substitutions similar to sed
$ var="abcde"; echo ${var/de/12}
abc12
Use a default value
$ default="hello"; unset var; echo ${var:-$default}
hello