Der [
Befehl ist ein gewöhnlicher Befehl. Obwohl die meisten Shells dies als integrierte Funktion für die Effizienz bereitstellen, werden die normalen syntaktischen Regeln der Shell eingehalten. [
ist genau gleichbedeutend mit test
, außer dass [
a ]
als letztes Argument benötigt wird und test
nicht.
Die doppelten Klammern [[ … ]]
sind spezielle Syntax. Sie wurden in ksh (einige Jahre später [
) eingeführt, da [
ihre korrekte Verwendung problematisch sein kann und [[
einige neue nette Ergänzungen zulässt, die Shell-Sonderzeichen verwenden. Zum Beispiel können Sie schreiben
[[ $x = foo && $y = bar ]]
weil der gesamte Bedingungsausdruck von der Shell analysiert wird, während er [ $x = foo && $y = bar ]
zuerst in zwei Befehle aufgeteilt [ $x = foo
und $y = bar ]
vom &&
Operator getrennt wird . In ähnlicher Weise ermöglichen doppelte Klammern Dinge wie die Pattern-Matching-Syntax, um z. B. [[ $x == a* ]]
zu testen, ob der Wert von mit x
beginnt a
; In einfachen Klammern wird dies a*
auf die Liste der Dateien ausgedehnt, deren Namen a
im aktuellen Verzeichnis beginnen. Doppelte Klammern wurden zuerst in ksh eingeführt und sind nur in ksh, bash und zsh verfügbar.
In einfachen Klammern müssen Sie Variablen wie an den meisten anderen Stellen in doppelte Anführungszeichen setzen, da es sich nur um Argumente für einen Befehl handelt (der zufällig der [
Befehl ist). In doppelten Klammern brauchen Sie keine doppelten Anführungszeichen, da die Shell keine Worttrennung oder Globen ausführt: Sie analysiert einen bedingten Ausdruck, keinen Befehl.
Eine Ausnahme besteht jedoch darin, [[ $var1 = "$var2" ]]
dass Sie die Anführungszeichen benötigen, wenn Sie einen Byte-zu-Byte-Vergleich von Zeichenfolgen durchführen $var2
möchten $var1
.
Eine Sache, mit der Sie nichts anfangen können, [[ … ]]
ist die Verwendung einer Variablen als Operator. Dies ist beispielsweise vollkommen legal (aber selten nützlich):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
In deinem Beispiel
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
der Befehl innerhalb der if
ist [
mit den 4 Argumente -d
, /home/mazimi/VirtualBox
, VMs
und ]
. Die Shell analysiert -d /home/mazimi/VirtualBox
und weiß dann nicht, was zu tun ist VMs
. Sie müssten verhindern, dass sich das Wort aufteilt ${dir}
, um einen wohlgeformten Befehl zu erhalten.
Verwenden Sie generell immer doppelte Anführungszeichen um Variablen- und Befehlssubstitutionen, es sei denn, Sie wissen, dass Sie das Ergebnis aufteilen und glätten möchten. Die wichtigsten Stellen, an denen es sicher ist, keine doppelten Anführungszeichen zu verwenden, sind:
- in einer Zuweisung:
foo=$bar
(aber beachten Sie, dass Sie die doppelten Anführungszeichen in export "foo=$bar"
oder in Array-Zuweisungen wie benötigen array=("$a" "$b")
);
- in einer
case
Aussage case $foo in …
:;
- in doppelte eckige Klammern außer auf der rechten Seite des
=
oder ==
Operator (es sei denn , Sie Pattern - Matching tun wollen): [[ $x = "$y" ]]
.
In all diesen Fällen ist es richtig, doppelte Anführungszeichen zu verwenden. Sie können also auch die erweiterten Regeln überspringen und die Anführungszeichen immer wieder verwenden.