Необходимы ли котировки для назначения локальной переменной?

Можно ли безопасно опускать кавычки с правой стороны локального назначения?

function foo {
    local myvar=${bar}
    stuff()
}

Меня в основном интересует bash, но любая информация о угловых случаях в других оболочках приветствуется.

28 голосов | спросил rahmu 25 +04002013-10-25T17:17:36+04:00312013bEurope/MoscowFri, 25 Oct 2013 17:17:36 +0400 2013, 17:17:36

2 ответа


32

Котировки необходимы в export foo="$var" или local foo="$var" (или readonly, typeset, declare и другая переменная, объявляющая команды ):

    dash литий>
  • sh из NetBSD (также на основе оболочки Almquist).
  • sh от FreeBSD 9.2 или старше (см. изменение в 9.3 )
  • yash
  • zsh с версиями до 5.1 в bash или sh (или для export var="$(cmd)" где zsh будет выполнять разделение слов в противном случае (а не глобирование)).

В противном случае расширение переменной было бы подвергнуто расщеплению слов и /или генерации имени файла, как в любом аргументе, для любой другой команды.

И не нужны в bash или ksh или sh из FreeBSD 9.3 или новее (где команда каким-то образом разбирается как какое-то назначение), а не zsh (где разбиение слова и генерация имени файла не выполняются неявно при расширении переменной).

Они необходимы в каждой оболочке (кроме zsh), хотя в таких вещах, как:

a="b=some value"
export "$a"

Или, в общем, если что-то осталось от = (включая =), или результат некоторого расширения (например, 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 необходимы в приведенных выше случаях, а также в bash, а также zsh (все версии), когда в sh.

Если export /local или некоторая его часть является результатом некоторого расширения (например, в cmd=export; "$cmd" a="$b" или даже export$(:) a="$b") или если export /local не является первым словом в командной строке (как в dryrun=; $dryrun export a="$b"), тогда кавычки нужны в каждом оболочка. В случае > /dev/null export a="$b", однако, кавычки не нужны в bash /AT & T ksh и zsh (они находятся в pdksh и производных).

Они не нужны в любой оболочке при написании:

foo=$var export foo

(этот синтаксис также совместим с оболочкой Bourne, но в случае bash и zsh работает только при эмуляции sh).

(обратите внимание, что var=value local var не следует использовать, поскольку поведение изменяется в разных оболочках).

Также остерегайтесь этого специального случая с помощью bash:

$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b

Моя рекомендация - всегда указывать.

ответил Stéphane Chazelas 25 +04002013-10-25T17:46:27+04:00312013bEurope/MoscowFri, 25 Oct 2013 17:46:27 +0400 2013, 17:46:27
2

Я обычно цитирую любое использование переменных, где могут быть такие символы, как пробелы. В противном случае вы столкнетесь с такими проблемами:

#!/bin/bash

bar="hi bye"

function foo {
  local myvar=${bar}
  printf "%s\n" $myvar
  printf "%s\n" "$myvar"
}

foo

Использование переменной в присваивании не нуждается в кавычках, но когда вы собираетесь использовать ее, например, в printf, вам нужно будет там указать:

  printf "%s\n" "$myvar"

ПРИМЕЧАНИЕ. Помните, что переменная $IFS определяет, что представляют собой разделители.

IFS    The  Internal  Field  Separator that is used for word splitting after 
       expansion and to split lines into words with the read builtin command. 
       The default value is ``<space><tab><newline>''.

Пример

С поддержкой отладки в Bash мы можем видеть, что происходит за кулисами.

$ bash -x cmd.bash 
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye

В вышесказанном мы видим, что переменная, $bar была передана с точностью до $myvar, но затем, когда мы пошли использовать $myvar, мы должны были понять содержание $myvar, когда мы пошли использовать его.

ответил slm 25 +04002013-10-25T17:26:59+04:00312013bEurope/MoscowFri, 25 Oct 2013 17:26:59 +0400 2013, 17:26:59

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132