2014-11-24 3 views
6

Практически везде, где я читал, в том числе руководство по стилю скриптов в стиле Google, упоминается необходимость цитирования подстановок команд (за исключением тех случаев, когда это было особенно желательно).Нужно ли указывать замену команд при присваивании переменных в bash?

Насколько я понимаю, когда/где/почему цитаты команд заменены во время общего использования. Например: echo "$(cat <<< "* useless string *")" вместо echo $(...)

Однако для присвоения переменных в частности, я видел так много примеров, как например: variable="$(command)"

Но я не нашел примеров, когда variable=$(command) не является эквивалентом.

variable="$(echo "*")" и variable=$(echo "*") оба устанавливают значение в '*'.

Может ли кто-нибудь дать ситуации, когда оставляющая подстановочную позицию без кавычек во время выбора переменной фактически вызовет проблему?

+0

Хороший вопрос! Я сделал много тестов, и похоже, что они точно такие же, никаких различий. – fedorqui

+0

Я думаю, что вопрос, о котором он спрашивает, может произойти с $ cmd, $ {cmd}. В подстановке и в предложениях If нам нужно «». Пожалуйста, исправьте, если я ошибаюсь –

ответ

6

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

variable=$(command) # same as variable="$(command)" 

Однако софистика выполняется перед выполнением команд, поэтому в

echo $(command) 
echo "$(command)" 

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

Интересная оболочечная причуда: есть еще одно место, где цитата о замещении или нет не имеет значения, а именно выражение в конструкции case expr in.

case $FOO in 
    (frob) ...;; 
esac 

неотличима от

case "$FOO" in 
    (frob) ...;; 
esac 
+2

Вот что говорит этот ответ. –

+0

Можете ли вы дать ссылку на точную часть стандарта POSIX, где это требуется? У меня проблемы с поиском. – Lucas

+2

@Lucas Я бы интерпретировал 2.9.1 Простые команды, # 4 в http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01: * «Каждое назначение переменной должно быть расширено для расширения тильды, параметр расширение, подстановку команд, арифметическое расширение и удаление цитат перед назначением значения ». * Здесь не говорится о разделении слов. – Jens

-2

тестирования с таким количеством различных команд, это то же самое. Невозможно найти разницу.

+1

Это не ответ на вопрос. И чтобы увидеть разницу, попробуйте 'echo $ (echo -e" hello \ nworld ")' против 'echo '$ (echo -e" hello \ nworld ")" ' – jeb

4

При использовании BASH, эти две линии 100% эквивалентны:

variable="$(command)" 
variable=$(command) 

пока эти два не являются:

echo $(command) 
echo "$(command)" 

Увы, человеческий мозг не компьютер. Это особенно не так надежно, когда приходится повторять работу.

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

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

Конфликты: поскольку первые две линии одинаковы, то в среднем мозгу легче всегда указывать $() (даже если это не обязательно), чтобы вы всегда указывали, когда вам нужно.

+2

Хорошо, тогда имеет смысл, почему это рекомендуется так часто ... Когда я впервые начал писать сценарии оболочки, я взял цитату в качестве общего правила. Теперь, когда я больше знаком с ним, я просто пытаюсь устранить все лишнее или ненужное. – Six

Смежные вопросы