Variablen in einem Shell-Skript referenzieren

8

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

    
Karnivaurus 09.10.2015, 12:55

2 Antworten

15

In den meisten Situationen sind sowohl $var als auch ${var} identisch. (Beachten Sie, dass Sie am Ende kein $ verwenden dürfen!)

Ein Beispiel für geschweifte Klammern ist, wenn Sie eine Variable in eine fortlaufende Zeichenfolge einfügen müssen.

Beispiel:

var=hel
echo ${var}lo

gibt hello aus.

    
Aizuddin Zali 09.10.2015, 13:09
11

Um Ihre Hauptfrage zu beantworten, wird ${foo} als "Parametererweiterung" bezeichnet. . Um genau zu sein, startet die $ selbst Parametererweiterung, die { } sind tatsächlich optional nach dem POSIX Spezifikation , kann aber nützlich sein, 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 sind $foo und ${foo} identisch. Abgesehen von Fällen wie den oben genannten oder wenn Sie String-Manipulation durchführen, sind sie völlig äquivalent .

Sie sollten jedoch keines von beiden wirklich verwenden. Als Faustregel gilt, dass Sie immer immer mit "$foo" oder "${foo}" und niemals mit $foo oder ${foo} verwenden sollten. Sie sollten Ihre Variablen immer zitieren, um zu vermeiden, den Split + Glob-Operator aufzurufen (mehr dazu später). Sie wollen sicherlich nicht $foo$ . Das letzte $ ist irrelevant:

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

Also, während nicht-quotierte Variablen manchmal in Ordnung sind:

$ echo $foo
bar

Sie sind normalerweise 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 ${foo} verwenden, teilt die Shell den in der Variablen gespeicherten Wert in whitespace auf (dies kann geändert werden, indem die Variable IFS auf etwas anderes gesetzt wird) Eine Liste und dann wird jedes Element der Liste als glob -Muster behandelt und in alle übereinstimmenden Dateien oder Verzeichnisse erweitert. 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 existiert?

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

Die Variable wurde in foo und * aufgeteilt, und da * ein Platzhalterzeichen ist, das mit einer beliebigen Zeichenfolge übereinstimmt, teilt Ihnen die Shell mit, dass eine Datei mit dem Namen foo * exxists vorhanden ist. Wenn wir es jedoch korrekt zitieren, passiert das 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 verdeutlichen. Stellen Sie sich vor, ich hätte rm anstelle von echo verwendet.

Also, erste Regel: zitieren Sie immer Ihre Variablen. Sie können entweder "$foo" oder "${foo}" verwenden, aber so oder so zitieren. Weitere Informationen zur sicheren Verwendung von Variablen finden Sie in diesen Posts:

terdon 09.10.2015 17:12

Tags und Links