я могу написать
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
конечный результат для меня все кажется примерно одинаковым. Почему я должен написать один или другой? какие-нибудь из них не переносимы / POSIX?
источник
я могу написать
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
конечный результат для меня все кажется примерно одинаковым. Почему я должен написать один или другой? какие-нибудь из них не переносимы / POSIX?
VAR=$VAR1
это упрощенная версия VAR=${VAR1}
. Второе может сделать то, что первое не может, например, сослаться на индекс массива (не переносимый) или удалить подстроку (переносимый POSIX). См. Раздел « Дополнительная информация о переменных » руководства Bash для начинающих и расширения параметров в спецификации POSIX.
Использование кавычек вокруг переменной, как в rm -- "$VAR1"
или rm -- "${VAR}"
является хорошей идеей. Это делает содержимое переменной атомарной единицей. Если значение переменной содержит пробелы (ну, символы в $IFS
специальной переменной, пробелы по умолчанию) или символы глобинга, и вы не заключаете его в кавычки, то каждое слово рассматривается для генерации имени файла (глобирования), расширение которого дает столько аргументов, сколько вы делаешь.
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
По переносимости: в соответствии с разделом 2.6.2 POSIX.1-2008 , фигурные скобки являются необязательными.
var1=$var
расширение дает ошибку?export VAR=$VAR1
. Что касается фигурных скобок, они являются необязательными (см. Четвертый абзац цитируемого вами раздела; это относится ко всем оболочкам до POSIX и POSIX).${VAR}
и$VAR
в точности эквивалентны. Для простого расширения переменной единственная причина использования${VAR}
- это когда синтаксический анализ в противном случае захватил бы слишком много символов в имя переменной, как в${VAR1}_$VAR2
(что без скобок было бы эквивалентно${VAR1_}$VAR2
). Наиболее украшенное разложение (${VAR:=default}
,${VAR#prefix}
, ...) требуют брекетов.В присваивании переменной разделение полей (то есть разделение в пустом пространстве в значении) и расширение имени пути (то есть глобализация) отключены, что
VAR=$VAR1
в точности эквивалентноVAR="$VAR1"
во всех оболочках POSIX и во всех pre-POSIX sh, о которых я слышал , (Ссылка POSIX: простые команды ). По той же причинеVAR=*
надежно устанавливаетVAR
буквальную строку*
; конечноVAR=a b
устанавливаетVAR
дляa
посколькуb
отдельное слово в первую очередь. Вообще говоря, двойные кавычки не нужны, когда синтаксис оболочки ожидает одно слово, например, вcase … in
(но не в шаблоне), но даже там вам нужно быть осторожным: например, POSIX указывает, чтоцели перенаправления (>$filename
) не требуют цитирования в сценариях, но некоторые оболочки, включая bash, требуют двойных кавычек даже в сценариях. См. Когда необходимо двойное цитирование? для более тщательного анализа.В других случаях вам нужны двойные кавычки, в частности,
export VAR="${VAR1}"
(которые можно эквивалентно записатьexport "VAR=${VAR1}"
) во многих оболочках (POSIX оставляет этот случай открытым). Сходство этого случая с простыми назначениями и рассеянный характер списка случаев, когда вам не нужны двойные кавычки, - вот почему я рекомендую просто использовать двойные кавычки, если вы не хотите разбивать и использовать глобальные символы.источник
IFS
символов, потому что я хочу быть в привычке. Единственным исключением является то, что я не цитирую значение при выполнении присваивания переменной (если не требуется, например, когда значение содержит пробел). Это делает подсветку синтаксиса редактора более полезной, когда есть подстановки команд, такие какFOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Вместо того, чтобы раскрашивать все в «строковый» цвет, я получаю подсветку синтаксиса вложенного кода. Это также, почему я избегаю кавычек.>$file
это нормально в сценариях POSIX, он не находится в bash, даже когда неинтерактивен (если только соблюдение POSIX не выполняется с помощью$POSIXLY_CORRECT
или--posix
...).VAR=$VAR1
, меня иногда удивляет тоlocal VAR=$VAR1
, что я помню, как по-другому работал, по крайней мере, в некоторых оболочках. Но я не могу воспроизвести расхождение.local VAR=$VAR1
это какexport VAR=$VAR1
, это зависит от оболочки.Цитата
Учтите, что двойные кавычки используются для раскрытия переменных, а одинарные кавычки используются для сильных кавычек, то есть без расширения.
Расширение:
Выход:
Возможно, стоит упомянуть, что вы должны использовать цитату везде, где это возможно, по нескольким причинам, среди которых лучшими являются то, что это считается наилучшей практикой, и для удобства чтения. Кроме того, потому что Bash иногда бывает причудливым и часто из-за кажущихся нелогичными или неразумными / неожиданными способами, а цитата меняет неявные ожидания на явные, что уменьшает эту поверхность ошибки (или потенциальную вероятность появления в ней).
И хотя вполне законно не цитировать и работать в большинстве случаев, эта функциональность предоставляется для удобства и, вероятно, менее переносима. полностью формальная практика, гарантирующая отражение намерений и ожиданий, заключается в цитировании.
подмена
Теперь рассмотрим также, что конструкция
"${somevar}"
используется для операций замещения. Несколько вариантов использования, таких как замена и массивы.Замена (зачистка):
Замена (замена):
Массивы:
Все это едва царапает поверхность конструкции
"${var}"
замещения. Оптимальной ссылкой для сценариев оболочки Bash является онлайновая ссылка libre, TLDP Проект документации Linuxhttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
источник
конец тогда:
стоит упомянуть в качестве более четкого примера использования фигурных скобок
источник