Ссылки на переменные в скрипте оболочки

Ссылки на переменные в скрипте оболочки

Если в скрипте оболочки я определяю переменную, например 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}"и никогда $fooor ${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вместо echothough.

Итак, первое правило:всегда заключайте переменные в кавычки.Вы можете использовать либо "$foo"или, "${foo}"но заключать в кавычки в любом случае. Для получения более подробной информации о безопасном использовании переменных, посмотрите эти посты:

Связанный контент