Кавычки против не кавычки переменной на RHS присвоения переменной - PullRequest
13 голосов
/ 18 октября 2010

В сценариях оболочки какая разница между этими двумя при назначении одной переменной другой:

a=$b

и

a="$b"

и когда мне следует использовать одну над другой?

Ответы [ 5 ]

6 голосов
/ 20 июня 2013

Я думаю, что здесь нет большой разницы. Да, желательно указывать переменную в двойных кавычках при обращении к этой переменной. Тем не менее, $x, кажется, не упоминается здесь в вашем вопросе.

y=$x само по себе не влияет на то, как будут обрабатываться пробелы. Только когда действительно используется * 1005, цитирование имеет значение. Например:

$ x=" a    b "
$ y=$x
$ echo $y
a b
$ echo "$y"
 a    b
6 голосов
/ 18 сентября 2014

Нет (веских) причин дважды заключать в кавычки RHS для присваивания переменной, когда он используется в качестве отдельного оператора.

RHS оператора присваивания не подлежит разделению слов (или расширению скобок)) и т. д., поэтому не нужно использовать кавычки для правильного назначения.Все другие расширения (насколько мне известно) происходят в RHS, но также встречаются в двойных кавычках, поэтому цитирование не имеет смысла.

При этом существуют причины, по которым не процитировать RHS.А именно как устранить ошибку "bash:! D ': событие не найдено" в подстановке команд Bash (см., В частности, мой ответ и ответ rici).

4 голосов
/ 25 мая 2018

С в разделе 2.9.1 спецификации синтаксиса оболочки POSIX:

Каждое назначение переменной должно быть расширено для расширения тильды, расширения параметра, подстановки команд, арифметикирасширение и удаление кавычек до присвоения значения.

Разделение строк и глобализация (шаги, которые подавляют двойные кавычки) в этом списке отсутствуют.

Таким образом,кавычки излишни во всех простых присваиваниях (не говоря уже о тех, которые реализованы с аргументами declare, export или подобными командами), за исключением тех, где (1) желательно поведение строк в одинарных, а не в двойных кавычках;или (2) пробел или другое содержимое в значении было бы иначе проанализировано как синтаксическое, а не буквальное.


(Обратите внимание, что решение о том, как анализировать команду - таким образом, является ли оноявляется присваиванием, простой командой, составной командой или чем-то еще - происходит до раскрытия параметров, таким образом, var=$1 определяется как присвоение до того, как значение $1 когда-либо будет считаться! Если бы это было неверно, так что данные могли бы незаметно стать синтаксисом, было бы гораздо сложнее - если не невозможно - написать безопасный код, обрабатывающий ненадежные данные в bash).

2 голосов
/ 30 декабря 2014

Вот еще несколько примеров: (наличие двух файлов в текущем каталоге t.sh и file)

a='$(ls)'        # no command substitution
b="$(ls)"        # command substitution, no word splitting
c='*'            # no filename expansion
d="*"            # no filename expansion
e=*              # no filename expansion
f=$a             # no expansions or splittings
g="$a"           # no expansions or splittings
h=$d             # no expansions or splittings

echo ---'$a'---
echo $a          # no command substitution
echo ---'$b'---
echo $b          # word splitting
echo ---'"$b"'---
echo "$b"        # no word splitting
echo ---'$c'---
echo $c          # filename expansion, word splitting
echo ---'"$c"'---
echo "$c"        # no filename expansion, no word splitting
echo ---'$d'---
echo $d          # filename expansion, word splitting
echo ---'"$d"'---
echo "$d"        # no filename expansion, no word splitting
echo ---'"$e"'---
echo "$e"        # no filename expansion, no word splitting 
echo ---'$e'---
echo $e          # filename expansion, word splitting
echo ---'"$f"'---
echo "$f"        # no filename expansion, no word splitting 
echo ---'"$g"'---
echo "$g"        # no filename expansion, no word splitting
echo ---'$h'---
echo $h          # filename expansion, word splitting
echo ---'"$h"'---
echo "$h"        # no filename expansion, no word splitting

Вывод:

---$a---
$(ls)
---$b---
file t.sh
---"$b"---
file
t.sh
---$c---
file t.sh
---"$c"---
*
---$d---
file t.sh
---"$d"---
*
---"$e"---
*
---$e---
file t.sh
---"$f"---
$(ls)
---"$g"---
$(ls)
---$h---
file t.sh
---"$h"---
*

Одна интересная вещь, на которую следует обратить вниманиезаключается в том, что подстановка команд происходит в присваиваниях переменных, если они заключены в двойные кавычки и если RHS задается явно как "$(ls)", а не неявно как "$a" ..

1 голос
/ 18 октября 2010

Расширенное руководство по написанию сценариев Bash: Глава 5: Цитирование

При ссылке на переменную это как правило, желательно приложить его имя в двойных кавычках. Это мешает реинтерпретация всего специального символы в строке в кавычках. Используйте двойные кавычки, чтобы предотвратить слово расщепление. Аргумент заключен в двойные кавычки представляют собой одно слово, даже если оно содержит разделители пробелов.

...