Могу ли я безопасно пропустить кавычки в правой части локального задания?
function foo {
local myvar=${bar}
stuff()
}
Я в основном заинтересован bash
, но любая информация о угловых коробках в других оболочках приветствуется.
Могу ли я безопасно пропустить кавычки в правой части локального задания?
function foo {
local myvar=${bar}
stuff()
}
Я в основном заинтересован bash
, но любая информация о угловых коробках в других оболочках приветствуется.
Ответы:
Котировки необходимы
export foo="$var"
илиlocal foo="$var"
(илиreadonly
,typeset
,declare
и другие переменные объявлении команд ) в:dash
sh
из NetBSD (также на основе Almquist оболочки).sh
Из FreeBSD 9.2 или старше (см изменений в 9.3 )yash
zsh
с версиями до 5.1 inksh
илиsh
эмуляцией (или для того,export var="$(cmd)"
гдеzsh
иначе можно было бы разделить слова (не используя globbing)).В противном случае расширение переменной будет подвержено разделению слов и / или генерации имени файла, как в любом аргументе любой другой команды.
И не нужны в:
bash
ksh
(все реализации)sh
из FreeBSD 9.3 или более поздней версииsh
(с 2005 года)zsh
В
zsh
, split + glob никогда не выполняется при расширении параметра, если только вsh
илиksh
эмуляция, но split (не glob) выполняется при замене команды. Начиная с версии 5.1,export
/local
и другие команды объявления стали командами с двумя ключевыми словами / встроенными, как в других оболочках выше, что означает, что в кавычках нет необходимости, даже вsh
/ksh
emulation и даже для подстановки команд.Существуют особые случаи, когда цитирование необходимо даже в этих оболочках, например:
Или, в более общем смысле, если что-либо, оставленное
=
(включая=
), заключено в кавычки или является результатом какого-либо расширения (напримерexport 'foo'="$var"
,export foo\="$var"
илиexport foo$((n+=1))="$var"
(это$((...))
также должно быть указано в действительности) ...). Или другими словами, когда аргументexport
не будет допустимым присваиванием переменной, если написано безexport
.Если
export
/local
имя команды сам котируются (даже в части , как"export" a="$b"
,'ex'port a="$b"
,\export a="$b"
или даже""export a="$b"
), кавычки вокруг$b
нужны только в AT & Tksh
иmksh
.Если
export
/local
или какая-то его часть является результатом некоторого расширения (например, вcmd=export; "$cmd" a="$b"
или дажеexport$(:) a="$b"
) или в подобных вещахdryrun=; $dryrun export a="$b"
), то кавычки необходимы в каждой оболочке.В случае
> /dev/null export a="$b"
, кавычки необходимыpdksh
и некоторые из его производных.Для
command export a="$b"
, кавычки необходимы в каждой оболочке, ноmksh
иksh93
(с теми же оговорками оcommand
иexport
не является результатом некоторого расширения).Они не нужны в любой оболочке, когда написано:
(этот синтаксис также совместим с оболочкой Bourne, но в последних версиях
zsh
работает только вsh
/ksh
emulation).(Обратите внимание, что
var=value local var
не следует использовать, так как поведение зависит от оболочки).Также обратите внимание, что использование
export
с присваиванием также означает, что статус выходаcmd
inexport var="$(cmd)"
потерян. Делать это какexport var; var=$(cmd)
будто нет этой проблемы.Также остерегайтесь этого особого случая с
bash
:Я бы посоветовал всегда цитировать.
источник
zsh
кавычках будут необходимы дляlocal foo="$(cmd)"
потому wordsplitting (но не имя файла поколение) будет выполняться для некотируемой подстановки команд (но не для некотируемых расширений параметров), еслиKSH_TYPESET
не включено, и в этом случае кавычка не нужна. Есть смысл? Нет? Тогда всегда цитируйте все, если вы точно не знаете, что делаете.Я обычно цитирую любое использование переменных, где могут быть такие символы, как пробелы. В противном случае вы столкнетесь с такими проблемами:
Использование переменной в присваивании, похоже, не требует кавычек, но когда вы собираетесь использовать ее, например, в
printf
кавычках, она вам понадобится:ПРИМЕЧАНИЕ. Помните, что именно эта переменная
$IFS
определяет символы разделителя.пример
С включенной отладкой в Bash мы можем видеть, что происходит за кулисами.
В приведенном выше примере мы видим, что переменная
$bar
была передана нормально,$myvar
но затем, когда мы перешли на использование,$myvar
мы должны были знать содержание того,$myvar
когда мы ее использовали.источник
bash
иksh
вlocal
/typeset
... Специальные модули).