it-swarm.com.de

Wann brauchen wir geschweifte Klammern um Shell-Variablen?

Wann verwenden wir in Shell-Skripten {} beim Erweitern von Variablen?

Ich habe zum Beispiel Folgendes gesehen:

var=10        # Declare variable

echo "${var}" # One use of the variable
echo "$var"   # Another use of the variable

Gibt es einen signifikanten Unterschied oder ist es nur Stil? Wird einer dem anderen vorgezogen?

577
New User

In diesem speziellen Beispiel macht es keinen Unterschied. Der {} in ${} ist jedoch nützlich, wenn Sie die Variable foo in der Zeichenfolge erweitern möchten

"${foo}bar"

da "$foobar" stattdessen die mit foobar angegebene Variable erweitern würde.

Geschweifte Klammern sind auch unbedingt erforderlich, wenn:

  • array-Elemente erweitern, wie in ${array[42]}
  • verwenden von Parametererweiterungsoperationen wie in ${filename%.*} (Erweiterung entfernen)
  • erweitern der Positionsparameter über 9 hinaus: "$8 $9 ${10} ${11}"

Dies überall zu tun, anstatt nur in potentiell mehrdeutigen Fällen, kann kann als gute Programmierpraxis angesehen werden. Dies dient sowohl der Konsistenz als auch der Vermeidung von Überraschungen wie $foo_$bar.jpg, bei denen es visuell nicht offensichtlich ist, dass der Unterstrich Teil des Variablennamens wird.

666
Fred Foo

Variablen werden ohne $ und ohne {} deklariert und zugewiesen. Sie müssen verwenden

var=10

zuweisen. Um aus der Variablen zu lesen (dh die Variable zu erweitern), müssen Sie $ verwenden.

$var      # use the variable
${var}    # same as above
${var}bar # expand var, and append "bar" too
$varbar   # same as ${varbar}, i.e expand a variable called varbar, if it exists.

Das hat mich manchmal verwirrt - in anderen Sprachen verweisen wir auf die Variable auf dieselbe Weise, unabhängig davon, ob sie sich links oder rechts von einer Zuweisung befindet. Aber Shell-Scripting ist anders, $var=10 macht nicht das, was Sie vielleicht denken!

117
Aaron McDaid

Sie verwenden {} zum Gruppieren. Die geschweiften Klammern sind erforderlich, um Array-Elemente dereferenzieren zu können. Beispiel:

dir=(*)           # store the contents of the directory into an array
echo "${dir[0]}"  # get the first entry.
echo "$dir[0]"    # incorrect
30
glenn jackman

Sie können auch Text innerhalb der geschweiften Klammern bearbeiten:

STRING="./folder/subfolder/file.txt"
echo ${STRING} ${STRING%/*/*}

Ergebnis:

./folder/subfolder/file.txt ./folder

oder

STRING="This is a string"
echo ${STRING// /_}

Ergebnis:

This_is_a_string

Sie sind direkt in "regulären Variablen" nicht erforderlich ... Aber es ist hilfreicher für das Debuggen und das Lesen eines Skripts.

26
SierraX

Das Ende des Variablennamens wird normalerweise durch ein Leerzeichen oder eine neue Zeile gekennzeichnet. Aber was ist, wenn wir nach dem Drucken des Variablenwerts kein Leerzeichen oder keine neue Zeile möchten? Die geschweiften Klammern teilen dem Shell-Interpreter mit, wo das Ende des Variablennamens liegt.

Klassisches Beispiel 1) - Shell-Variable ohne nachfolgendes Leerzeichen

TIME=10

# WRONG: no such variable called 'TIMEsecs'
echo "Time taken = $TIMEsecs"

# What we want is $TIME followed by "secs" with no whitespace between the two.
echo "Time taken = ${TIME}secs"

Beispiel 2) Java Klassenpfad mit versionierten Gläsern

# WRONG - no such variable LATESTVERSION_src
CLASSPATH=hibernate-$LATESTVERSION_src.Zip:hibernate_$LATEST_VERSION.jar

# RIGHT
CLASSPATH=hibernate-${LATESTVERSION}_src.Zip:hibernate_$LATEST_VERSION.jar

(Freds Antwort besagt dies bereits, aber sein Beispiel ist etwas zu abstrakt.)

11

Entsprechend dem Vorschlag von SierraX und Peter zur Textmanipulation werden geschweifte Klammern {} verwendet, um eine Variable an einen Befehl zu übergeben. Beispiel:

Angenommen, Sie haben eine sposi.txt -Datei, die die erste Zeile eines bekannten italienischen Romans enthält:

> sposi="somewhere/myfolder/sposi.txt"
> cat $sposi

Ausgabe: quel ramo del lago di como che volge a mezzogiorno

Erstellen Sie nun zwei Variablen:

# Search the 2nd Word found in the file that "sposi" variable points to
> Word=$(cat $sposi | cut -d " " -f 2)

# This variable will replace the Word
> new_Word="filone"

Ersetzen Sie nun den Inhalt der Variablen Word durch new_Word in der Datei sposi.txt

> sed -i "s/${Word}/${new_Word}/g" $sposi
> cat $sposi

Ausgabe: quel filone del lago di como che volge a mezzogiorno

Das Wort "ramo" wurde ersetzt.

2
Fabio Natalini

Geschweifte Klammern werden immer benötigt, um auf Array-Elemente zuzugreifen und eine Klammererweiterung durchzuführen.

Es ist gut, nicht übervorsichtig zu sein und {} für die Shell-Variablenerweiterung zu verwenden, auch wenn es keinen Raum für Mehrdeutigkeiten gibt.

Zum Beispiel:

dir=log
prog=foo
path=/var/${dir}/${prog}      # excessive use of {}, not needed since / can't be a part of a Shell variable name
logfile=${path}/${prog}.log   # same as above, . can't be a part of a Shell variable name
path_copy=${path}             # {} is totally unnecessary
archive=${logfile}_Arch       # {} is needed since _ can be a part of Shell variable name

Es ist also besser, die drei Zeilen wie folgt zu schreiben:

path=/var/$dir/$prog
logfile=$path/$prog.log
path_copy=$path

das ist definitiv besser lesbar.

Da ein Variablenname nicht mit einer Ziffer beginnen kann, benötigt Shell {} für nummerierte Variablen (wie $1, $2 usw.) nur, wenn auf diese Erweiterung eine Ziffer folgt. Das ist zu subtil und es macht Sinn, {} in solchen Kontexten explizit zu verwenden:

set app      # set $1 to app
fruit=$1le   # sets fruit to Apple, but confusing
fruit=${1}le # sets fruit to Apple, makes the intention clear

Sehen:

1
codeforester