В сценарии оболочки, если я определяю переменную, такую как FOO=25
, есть ли разница между ссылками на нее как $FOO$
и ${FOO}$
?
В большинстве ситуаций и $var
и ${var}
то же. (Обратите внимание, что Вы не должны использовать $
в конце!)
Один пример, где Вам нужны фигурные скобки, - когда Вы должны поместить переменную в непрерывную последовательность.
Пример:
var=hel
echo ${var}lo
произведет hello
.
Отвечать на Ваш основной вопрос, ${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"
или "${foo}"
и никогда $foo
или ${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
переменная к чему-то еще) в список и затем, каждый элемент списка рассматривают как шаблон шарика и расширяют в любые файлы или каталоги соответствия. Это известно как split+glob оператор. Для иллюстрирования рассмотрите каталог с двумя файлами:
$ 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 *
существует. Однако, если мы заключаем его в кавычки правильно, этого не происходит:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Это было тривиальным примером, чтобы проиллюстрировать тезис. Вообразите, использовал ли я rm
вместо echo
все же.
Так, сначала управляйте: всегда заключайте свои переменные в кавычки. Можно использовать также "$foo"
или "${foo}"
но заключите его в кавычки так или иначе. Для большего количества детали об использовании переменных безопасно, взгляните на эти сообщения:
sudo find / -name "avcodec.h"
(это должно возвратить местоположение заголовочного файла avcodec.h
, который, как предполагается, установлен с пакетом libavcodec), я ничего не получаю. Таким образом, это подтверждает, что другие пакеты являются not' t быть установленным.
– shinvu
31 December 2016 в 03:57