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 $varund ${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 $foound ${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 $foooder ${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 $foooder verwenden ${foo}, teilt die Shell den in der Variablen im Leerzeichen gespeicherten Wert (dies kann geändert werden, indem die IFSVariable 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 foound *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 rmstattdessen 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 varnirgendwo.
$am Ende nicht benutzen ! Es wird als normales Zeichen und nicht als Teil des Variablennamens behandelt.