Разница между одинарными и двойными кавычками в Bash - PullRequest
458 голосов
/ 14 июля 2011

В Bash, чем отличаются одинарные кавычки ('') и двойные кавычки ("")?

Ответы [ 6 ]

468 голосов
/ 14 июля 2011

Одинарные кавычки ничего не будут интерполировать, но двойные кавычки будут.Например: переменные, обратные пометки, некоторые \ экранированные символы и т. Д.

Пример:

$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")

В руководстве по Bash есть следующее:

3.1.2.2 Одинарные кавычки

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

3.1.2.3 Двойные кавычки

Заключение символов в двойные кавычки (") сохраняет буквальное значение всех символов в кавычках, за исключением $, `, \ и, когда включено расширение истории, !.Символы $ и ` сохраняют свое особое значение в двойных кавычках (см. Расширения оболочки ).Обратная косая черта сохраняет свое специальное значение только тогда, когда за ней следует один из следующих символов: $, `, ", \ или перевод строки.В двойных кавычках удаляются обратные слэши, за которыми следует один из этих символов.Обратная косая черта предшествующих символов без специального значения остается неизменной.Двойная кавычка может быть заключена в двойные кавычки, если им предшествует обратная косая черта.Если включено, расширение истории будет выполняться до тех пор, пока ! в двойных кавычках не будет экранировано с помощью обратной косой черты.Обратная косая черта, предшествующая !, не удаляется.

Специальные параметры * и @ имеют особое значение в двойных кавычках (см. Расширение параметров оболочки ).

213 голосов
/ 14 июля 2011

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

Например, это

#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'

даст это:

double quotes gives you sometext
single quotes gives you $MYVAR
188 голосов
/ 07 февраля 2017

принятый ответ отлично.Я делаю таблицу, которая помогает в быстром понимании темы.Объяснение включает в себя простую переменную a, а также индексированный массив arr.

Если мы установим

a=apple      # a simple variable
arr=(apple)  # an indexed array with a single element

, а затем echo выражение во втором столбце, мыполучит результат / поведение, показанное в третьем столбцеЧетвертый столбец объясняет поведение.

 # | Expression  | Result      | Comments
---+-------------+-------------+--------------------------------------------------------------------
 1 | "$a"        | apple       | variables are expanded inside ""
 2 | '$a'        | $a          | variables are not expanded inside ''
 3 | "'$a'"      | 'apple'     | '' has no special meaning inside ""
 4 | '"$a"'      | "$a"        | "" is treated literally inside ''
 5 | '\''        | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
 6 | "red$arocks"| red         | $arocks does not expand $a; use ${a}rocks to preserve $a
 7 | "redapple$" | redapple$   | $ followed by no variable name evaluates to $
 8 | '\"'        | \"          | \ has no special meaning inside ''
 9 | "\'"        | \'          | \' is interpreted inside "" but has no significance for '
10 | "\""        | "           | \" is interpreted inside ""
11 | "*"         | *           | glob does not work inside "" or ''
12 | "\t\n"      | \t\n        | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi          | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi`   | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]}   | array access not possible inside ''
16 | "${arr[0]}" | apple       | array access works inside ""
17 | $'$a\''     | $a'         | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'"     | $'\t'       | ANSI-C quoting is not interpreted inside ""
19 | '!cmd'      | !cmd        | history expansion character '!' is ignored inside ''
20 | "!cmd"      | cmd args    | expands to the most recent command matching "cmd"
21 | $'!cmd'     | !cmd        | history expansion character '!' is ignored inside ANSI-C quotes
---+-------------+-------------+--------------------------------------------------------------------

См. Также:

6 голосов
/ 14 июля 2018

Другие очень хорошо объяснили и просто хотят привести простые примеры.

Одинарные кавычки можно использовать вокруг текста, чтобы оболочка не интерпретировала какие-либо специальные символы. Знаки доллара, пробелы, амперсанды, звездочки и другие специальные символы игнорируются, если заключены в одинарные кавычки.

$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.' 

Это даст это:

All sorts of things are ignored in single quotes, like $ & * ; |.

Единственное, что не может быть заключено в одинарные кавычки, это одиночная кавычка.

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

$ echo "Here's how we can use single ' and double \" quotes within double quotes"

Это даст это:

Here's how we can use single ' and double " quotes within double quotes

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

$ echo "The current Oracle SID is $ORACLE_SID"

Это даст:

The current Oracle SID is test

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

$ today=`date '+%A, %B %d, %Y'`
$ echo $today 

Это даст это:

Monday, September 28, 2015 
1 голос
/ 02 января 2019

Поскольку это фактический ответ при работе с кавычками в bash, я добавлю еще один момент, пропущенный в ответах выше, при работе с арифметическими операторами в оболочке.

Оболочка bash поддерживает два способа выполнения арифметических операций, один из которых определяется встроенной командой let и оператором $((..)). Первое вычисляет арифметическое выражение, в то время как второе является скорее составным выражением.

Важно понимать, что арифметическое выражение, используемое с let, подвергается разделению слов, расширению пути, как и любые другие команды оболочки. Так что правильное цитирование и экранирование должны быть сделаны.

См. Этот пример при использовании let

let 'foo = 2 + 1'
echo $foo
3

Использование одинарных кавычек здесь абсолютно нормально, так как здесь нет необходимости в расширении переменных, рассмотрим случай

bar=1
let 'foo = $bar + 1'

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

let 'foo = '"$bar"' + 1'

Это должно быть одной из причин, $((..)) всегда следует рассматривать как использование let. Потому что внутри него содержимое не подлежит расщеплению. Предыдущий пример с использованием let можно просто записать как

(( bar=1, foo = bar + 1 ))

Всегда не забывайте использовать $((..)) без одинарных кавычек

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

printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2

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

curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'

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

0 голосов
/ 19 августа 2018

Существует четкое различие между использованием ' ' и " ".

Когда ' ' используется вокруг чего-либо, «преобразование или перевод» не выполняется.Он напечатан как есть.

С " " все, что его окружает, «переводится или трансформируется» в его значение.

Под переводом / преобразованием я подразумеваю следующее: все, что находится в одинарных кавычках, не будет «переведено» в их значения.Они будут приняты, как они находятся внутри кавычек.Пример: a=23, тогда echo '$a' выдаст $a на стандартном выходе.Принимая во внимание, что echo "$a" будет производить 23 на стандартном выходе.

...