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

помещение попытки:

export TERM=xterm-256color

в Вашем bashrc.

Это должно зафиксировать его...

37
22.04.2017, 02:08
2 ответа

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

  • dash
  • sh из NetBSD (также на основе оболочки Almquist).
  • sh из FreeBSD 9.2 или более старый (см. изменение в 9,3),
  • yash
  • zsh с версиями до 5,1 дюймов ksh или sh эмуляция (или для export var="$(cmd)" где zsh выполнил бы слово, разделяющее иначе (не globbing)).

Поскольку иначе переменное расширение подверглось бы разделению слова и/или поколению имени файла как в любом аргументе любой другой команде.

И не нужны в:

  • bash
  • ksh (все реализации)
  • sh из FreeBSD 9.3 или более новый
  • busybox', основанный на пепле sh (с 2005)
  • zsh

В zsh, split+glob никогда не делается после расширения параметра, если в sh или ksh эмуляция, но разделение (не шарик) сделана на замену команды. Начиная с версии 5.1, export/local и другие команды объявления стали двойным ключевым словом / встроенными командами как в других оболочках выше, что означает заключать в кавычки, не необходимо, даже в sh/ksh эмуляция и даже для замены команды.

Существуют особые случаи, где заключение в кавычки необходимо даже в тех оболочках хотя как:

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 необходимы кроме AT&T ksh и 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 не будучи результатом некоторого расширения).

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

foo=$var export foo

(что синтаксис, являющийся также совместимым с Оболочкой Bourne, но в последних версиях zsh, только работа, когда в sh/ksh эмуляция).

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

Также отметьте то использование export с присвоением также означает что статус выхода cmd в export var="$(cmd)" потерян. Выполнение его как export var; var=$(cmd) не имеет той проблемы.

Также остерегайтесь этого особого случая с bash:

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

Мой советовать должен был бы всегда заключать в кавычки.

42
27.01.2020, 19:36
  • 1
    Отметьте это в zsh кавычки необходимы для local foo="$(cmd)" потому что wordsplitting (но не поколение имени файла) выполняется для неупомянутых замен команды (но не для неупомянутых расширений параметра), если KSH_TYPESET включен, в этом случае кавычки не необходимы. Иметь смысл? Нет? Затем всегда заключайте все в кавычки, если Вы не знаете точно, что Вы делаете. снимок экрана –  Matt 25.10.2013, 20:39
  • 2
    @Matt, я люблю Ваше заключение.:D Это забавно, большая часть того, что я изучил сценариев оболочки, прибыл из этого stackexchange, так, чтобы я не понимал, что всегда заключают Ваши переменные в кавычки, не общепринятая истина среди устройств записи сценария. Я нахожу, что у меня есть большое договаривание сделать существующих производственных сценариев, записанных людьми, которые не заключили в кавычки и не знали точно, что они делали.... –  Wildcard 06.01.2016, 06:09

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

#!/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 когда мы пошли для использования его.

3
27.01.2020, 19:36
  • 1
    не является единственной проблемой с неупомянутыми переменными, необходимо рассмотреть поколение имени файла (иначе globbing) также (хотя это (и) не применяется в переменных присвоениях и для bash и ksh в local/typeset... специальный builtins). –  Stéphane Chazelas 25.10.2013, 16:58

Теги

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