Referenzieren von Variablen in einem Shell-Skript

Referenzieren von Variablen in einem Shell-Skript

Wenn ich in einem Shell-Skript eine Variable wie definiere FOO=25, besteht dann ein Unterschied zwischen der Referenzierung als $FOO$und ${FOO}$?

Antwort1

In den meisten Fällen sind $varund identisch. (Beachten Sie, dass Sie am Ende ${var}kein „a“ verwenden dürfen !)$

Geschweifte Klammern sind beispielsweise erforderlich, wenn Sie eine Variable in eine fortlaufende Zeichenfolge einfügen müssen.

Beispiel:

var=hel
echo ${var}lo

wird ausgegeben hello.

Antwort2

Um Ihre Hauptfrage zu beantworten, ${foo}heißt"Parametererweiterung". Genauer gesagt $startet die Parametererweiterung selbst, die { }eigentlich optional sind, gemäßdie POSIX-Spezifikation, kann aber nützlich sein, um das Ende des Variablennamens anzuzeigen:

$ foo="bar"
$ echo $fooBaz   ## fails, no variable named $fooBaz exists

$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz

Im Grunde genommen sind $foound ${foo}identisch. Abgesehen von Fällen wie oben oder wenn SieZeichenfolgenmanipulation, sie sind völlig gleichwertig.

Sie sollten jedoch keines von beiden verwenden. Die Faustregel lautet, dass Sie mit sehr wenigen Ausnahmenstetsverwenden Sie "$foo"oder "${foo}"und niemals $foooder ${foo}. Sie sollten Ihre Variablen immer in Anführungszeichen setzen, um den Aufruf des Operators split+glob zu vermeiden (mehr dazu später). Sie möchten sicherlich nicht $foo$. Das letzte $ist irrelevant:

$ foo="bar"
$ echo "$foo$"
bar$

Obwohl Variablen ohne Anführungszeichen manchmal in Ordnung sind:

$ echo $foo
bar

Dies ist in der Regel nicht der Fall und sollte unbedingt 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 nichts 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}, wird die ShellTeiltder in der Variable gespeicherte Wert bei Leerzeichen (dies kann geändert werden, indem die IFSVariable auf etwas anderes gesetzt wird) in eine Liste und dann wird jedes Element der Liste als einGlobusMuster und in alle passenden Dateien oder Verzeichnisse erweitert. Dies wird alsteilen+globusOperator. 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

Lassen Sie uns nun eine Variable auf Folgendes setzen foo *:

$ foo="foo *"

Was passiert, wenn wir versuchen zu überprüfen, ob eine Datei mit diesem Namen existiert?

$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists

Die Variable wurde in foound aufgeteilt *. Da *es sich bei und um ein Platzhalterzeichen handelt, das mit jedem String übereinstimmt, teilt Ihnen die Shell mit, dass eine Datei mit dem Namen foo *existiert. Wenn wir sie jedoch korrekt 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 zur Veranschaulichung. Stellen Sie sich vor, ich hätte rmstatt verwendet echo.

Also, erste Regel:Setzen Sie Ihre Variablen immer in Anführungszeichen.Sie können entweder "$foo"oder verwenden "${foo}", aber in beiden Fällen müssen Sie es in Anführungszeichen setzen. Weitere Einzelheiten zur sicheren Verwendung von Variablen finden Sie in diesen Beiträgen:

verwandte Informationen