
Если в скрипте оболочки я определяю переменную, например FOO=25
, есть ли разница между ссылкой на нее как $FOO$
и ${FOO}$
?
решение1
В большинстве случаев и — это одно $var
и то же. (Обратите внимание, что в конце ${var}
нельзя использовать a !)$
Одним из примеров, когда вам понадобятся фигурные скобки, является ситуация, когда вам нужно поместить переменную в непрерывную строку.
Пример:
var=hel
echo ${var}lo
выведет hello
.
решение2
Чтобы ответить на ваш главный вопрос, ${foo}
называется"расширение параметров". Если быть точным, то $
сам по себе начинает расширение параметров, которые { }
на самом деле являются необязательными согласноспецификация POSIX, но может быть полезно для указания конца имени переменной:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
В принципе, $foo
и ${foo}
идентичны. За исключением случаев, подобных вышеприведенным, или когда вы делаетеманипуляция строками, они полностью эквивалентны.
Однако вам не следует использовать ни один из них. Правило большого пальца заключается в том, что, за очень редкими исключениями, вам следуетвсегдаиспользуйте "$foo"
or "${foo}"
и никогда $foo
or ${foo}
. Вы всегда должны заключать переменные в кавычки, чтобы избежать вызова оператора split+glob (подробнее об этом позже). Вы определенно не хотите $foo$
. Финал $
не имеет значения:
$ foo="bar"
$ echo "$foo$"
bar$
Итак, хотя переменные без кавычек иногда допустимы:
$ echo $foo
bar
Обычно они таковыми не являются и их действительно следует избегать:
$ 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
Обратите внимание, что скобки здесь тоже не помогают:
$ 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
При использовании $foo
или ${foo}
оболочка будетрасколотьзначение, сохраненное в переменной на пробеле (это можно изменить, установив IFS
переменную на что-то другое) в список, а затем каждый элемент списка обрабатывается какшаршаблон и расширен в любые соответствующие файлы или каталоги. Это известно каксплит+глобоператор. Для иллюстрации рассмотрим каталог с двумя файлами:
$ 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
Теперь давайте установим переменную foo *
:
$ foo="foo *"
Что произойдет, если мы попытаемся проверить, существует ли файл с таким именем?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
Переменная была разделена на foo
и *
и, поскольку *
является подстановочным знаком, который соответствует любой строке, оболочка сообщает вам, что файл с именем foo *
exxists. Однако, если мы правильно заключим его в кавычки, этого не произойдет:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Это был тривиальный пример, иллюстрирующий суть. Представьте, если бы я использовал rm
вместо echo
though.
Итак, первое правило:всегда заключайте переменные в кавычки.Вы можете использовать либо "$foo"
или, "${foo}"
но заключать в кавычки в любом случае. Для получения более подробной информации о безопасном использовании переменных, посмотрите эти посты: