10

Когда нужны фигурные скобки вокруг переменных в оболочке?

10

Описание проблемы:

В шелл-скриптах когда нужно использовать фигурные скобки при расширении переменных?

Например, я встречал следующий код:

var=10        # Объявление переменной

echo "${var}" # Один из способов использования переменной
echo "$var"   # Другой способ использования переменной

Существует ли значительная разница между этими двумя способами, или это просто вопрос стиля? Предпочитается ли один способ над другим?

5 ответ(ов)

11

В данном конкретном примере разницы не делает. Однако фигурные скобки {} в ${} полезны, если вы хотите расширить переменную foo в строке

"${foo}bar"

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

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

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

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

1

Переменные в Bash объявляются и присваиваются без $ и без {}. Для присваивания значения переменной используется следующий синтаксис:

var=10

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

$var      # использование переменной
${var}    # то же самое, что и выше
${var}bar # развернуть var и добавить "bar" после него
$varbar   # то же самое, что и ${varbar}, т.е. развернуть переменную с именем varbar, если она существует

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

0

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

dir=(*)           # сохраняем содержимое директории в массив
echo "${dir[0]}"  # получаем первый элемент.
echo "$dir[0]"    # некорректно
0

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

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

Результат:

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

Или:

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

Результат:

This_is_a_string

Вы правы в том, что "обычные переменные" не являются обязательными... Но они могут быть более полезными для отладки и читаемости скрипта.

0

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

Классический пример 1) - переменная оболочки без завершающего пробела

TIME=10

# Неверно: переменной 'TIMEsecs' не существует
echo "Время затраченное = $TIMEsecs"

# То, что нам нужно, это $TIME, за которым следует "secs" без пробела между ними.
echo "Время затраченное = ${TIME}secs"

Пример 2) Java classpath с версиями jar-файлов

# Неверно - переменной LATESTVERSION_src не существует
CLASSPATH=hibernate-$LATESTVERSION_src.zip:hibernate_$LATEST_VERSION.jar

# Верно
CLASSPATH=hibernate-${LATESTVERSION}_src.zip:hibernate_$LATEST_VERSION.jar

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь