Когда нам нужны фигурные скобки вокруг переменных оболочки? - PullRequest
565 голосов
/ 05 января 2012

В сценариях оболочки, когда мы используем {} при расширении переменных?

Например, я видел следующее:

var=10        # Declare variable

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

Есть ли существенная разница или это просто стиль? Один предпочтительнее другого?

Ответы [ 7 ]

650 голосов
/ 05 января 2012

В этом конкретном примере это не имеет значения. Однако {} в ${} полезны, если вы хотите развернуть переменную foo в строке

"${foo}bar"

, поскольку "$foobar" вместо этого расширит переменную, обозначенную foobar.

Фигурные скобки также безоговорочно требуются, когда:

  • расширение элементов массива, как в ${array[42]}
  • с использованием операций расширения параметров, как в ${filename%.*} (удалить расширение)
  • расширение позиционных параметров за пределы 9: "$8 $9 ${10} ${11}"

Делая это везде, вместо просто неоднозначных случаев, можно считать хорошей практикой программирования. Это как для согласованности, так и во избежание неожиданностей, таких как $foo_$bar.jpg, где визуально не очевидно, что подчеркивание становится частью имени переменной.

115 голосов
/ 06 января 2012

Переменные объявляются и присваиваются без $ и без {}. Вы должны использовать

var=10

назначить. Чтобы читать из переменной (другими словами, «развернуть» переменную), вы должны использовать $.

$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.

Это иногда смущало меня - в других языках мы обращаемся к переменной одинаково, независимо от того, находится она слева или справа от присваивания. Но сценарии оболочки отличаются, $var=10 не делает то, что вы думаете, что делает!

30 голосов
/ 06 января 2012

Вы используете {} для группировки. Скобки необходимы для разыменования элементов массива. Пример:

dir=(*)           # store the contents of the directory into an array
echo "${dir[0]}"  # get the first entry.
echo "$dir[0]"    # incorrect
26 голосов
/ 14 февраля 2014

Вы также можете выполнять некоторые манипуляции с текстом внутри фигурных скобок:

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

Результат:

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

или

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

Результат:

This_is_a_string

Вы правы, в "обычных переменных" нет необходимости ... Но это более полезно для отладки и чтения сценария.

11 голосов
/ 26 апреля 2017

Конец имени переменной обычно обозначается пробелом или переводом строки.Но что, если мы не хотим пробела или новой строки после печати значения переменной?Фигурные скобки указывают интерпретатору оболочки, где находится конец имени переменной.

Классический пример 1) - переменная оболочки без конечных пробелов

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"

Пример 2) Java classpath с версионными банками

# 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

(ответ Фреда уже говорит об этом, но его пример слишком абстрактен)

2 голосов
/ 17 января 2018

В соответствии с предложением SierraX и Питера о работе с текстом, фигурные скобки {} используются для передачи переменной в команду, например:

Допустим, у вас есть файл sposi.txt содержит первую строку итальянского известного романа:

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

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

Теперь создайте две переменные:

# 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"

Теперь подставьте word переменное содержимое с одним из new_word , внутри файла sposi.txt

> sed -i "s/${word}/${new_word}/g" $sposi
> cat $sposi

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

Слово "ramo"был заменен.

1 голос
/ 21 марта 2019

Вьющиеся фигурные скобки всегда необходимы для доступа к элементам массива и выполнения расширения фигурных скобок.

Хорошо не проявлять чрезмерную осторожность и использовать {} для расширения переменных оболочки, даже если нет места для неоднозначности.

Например:

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

Итак, лучше написать три строки следующим образом:

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

, что определенно более читабельно.

Поскольку имя переменной не может начинаться с цифры, оболочке не требуется {} вокруг пронумерованных переменных (например, $1, $2 и т. Д.), Если за таким расширением не следует цифра.Это слишком тонко, и это делает явным использование {} в таких контекстах:

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

См .:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...