Разница между одиночными и двойными кавычками в Bash

В Bash, каковы различия между одинарными кавычками ('') и двойными кавычками ("")?

430
14 июля '11 в 20:55
источник поделиться
7 ответов

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

Пример:

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

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

3.1.2.2 Отдельные кавычки

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

3.1.2.3 Двойные котировки

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

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

443
14 июля '11 в 20:57
источник

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

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

#!/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
206
14 июля '11 в 21:02
источник

Принятый ответ великолепен. Я делаю таблицу, которая помогает в быстром понимании темы. Объяснение включает в себя простую переменную 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
---+-------------+-------------+--------------------------------------------------------------------

Смотрите также:

176
07 февр. '17 в 9:14
источник

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

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

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

Это даст следующее:

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

Единственная вещь, которая не может быть помещена в одинарные кавычки, - это одиночная цитата.

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

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

Это даст следующее:

Here 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 
5
14 июля '18 в 21:21
источник

Поскольку это де-факто ответ при работе с кавычками в 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 поле.

1
02 янв. '19 в 19:18
источник

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

Когда ' ' используется во всем, нет "трансформации или перевода". Он печатается так, как есть.

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

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

0
19 авг. '18 в 11:43
источник

Помимо интерполяции одиночная кавычка также используется для преобразования вывода комманда в строку.

Например, Если вы хотите использовать результат из lynx --dump www.example.com|grep "something" в другой программе, скажем, филе, вы можете использовать одинарные кавычки, чтобы упростить вашу работу вместо копирования и вставки (что, в свою очередь, невозможно в сценариях).

#!/bin/sh
figlet "`lynx --dump www.example.com|grep "something" `"
-5
03 дек. '17 в 3:32

Посмотрите другие вопросы по меткам или Задайте вопрос