Wenn ich in einem Shell-Skript eine Variable wie z. B. definiere FOO=25
, gibt es einen Unterschied zwischen der Referenzierung als $FOO$
und ${FOO}$
?
Wenn ich in einem Shell-Skript eine Variable wie z. B. definiere FOO=25
, gibt es einen Unterschied zwischen der Referenzierung als $FOO$
und ${FOO}$
?
Antworten:
In den meisten Situationen sind beide $var
und ${var}
gleich. (Beachten Sie, dass Sie $
am Ende kein a verwenden dürfen !)
Ein Beispiel, bei dem Sie geschweifte Klammern benötigen, ist, wenn Sie eine Variable in eine fortlaufende Zeichenfolge einfügen müssen.
Beispiel:
var=hel
echo ${var}lo
wird ausgegeben hello
.
Zur Beantwortung Ihrer Hauptfrage ${foo}
heißt "Parametererweiterung" . Um genau zu sein, $
startet das selbst die Parametererweiterung, die { }
gemäß der POSIX-Spezifikation tatsächlich optional sind , aber nützlich sein kann, um das Ende des Variablennamens anzugeben:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
Grundsätzlich $foo
und ${foo}
sind identisch. Abgesehen von Fällen wie den oben genannten oder wenn Sie eine Zeichenfolgenmanipulation durchführen , sind sie völlig gleichwertig.
Sie sollten jedoch keines von beiden wirklich verwenden. Als Faustregel ist , dass mit sehr wenigen Ausnahmen abgesehen, sollten Sie immer verwenden "$foo"
oder "${foo}"
und nie $foo
oder ${foo}
. Sie sollten Ihre Variablen immer in Anführungszeichen setzen, um den Aufruf des Operators split + glob zu vermeiden (dazu später mehr). Das willst du bestimmt nicht $foo$
. Das Finale $
ist irrelevant:
$ foo="bar"
$ echo "$foo$"
bar$
Während also nicht zitierte Variablen manchmal in Ordnung sind:
$ echo $foo
bar
Sie sind in der Regel nicht und sollten wirklich vermieden werden:
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Beachten Sie, dass die Klammern auch hier nicht helfen:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Wenn Sie $foo
oder verwenden ${foo}
, teilt die Shell den in der Variablen im Leerzeichen gespeicherten Wert (dies kann geändert werden, indem die IFS
Variable auf einen anderen Wert gesetzt wird ) in eine Liste auf. Anschließend wird jedes Element der Liste als Glob- Muster behandelt und erweitert alle passenden Dateien oder Verzeichnisse. Dies wird als Split + Glob- Operator bezeichnet. Betrachten Sie zur Veranschaulichung ein Verzeichnis mit zwei Dateien:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
Setzen wir nun eine Variable auf foo *
:
$ foo="foo *"
Was passiert, wenn wir versuchen zu überprüfen, ob eine Datei mit diesem Namen vorhanden ist?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
Die Variable wurde in aufgeteilt foo
und *
da *
es sich um einen Platzhalter handelt, der mit einer beliebigen Zeichenfolge übereinstimmt, teilt Ihnen die Shell mit, dass eine Datei mit dem Namen foo *
exxists vorhanden ist. Wenn wir es jedoch richtig zitieren, passiert dies nicht:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Das war ein triviales Beispiel, um den Punkt zu veranschaulichen. Stellen Sie sich vor, ich hätte rm
stattdessen verwendet echo
.
Also, erste Regel: Zitieren Sie immer Ihre Variablen. Sie können entweder "$foo"
oder "${foo}"
aber so oder so zitieren. Weitere Informationen zur sicheren Verwendung von Variablen finden Sie in den folgenden Beiträgen:
$ var="foo *"
sein $ foo="foo *"
? Sie verwenden var
nirgendwo.
$
am Ende nicht benutzen ! Es wird als normales Zeichen und nicht als Teil des Variablennamens behandelt.