Одинарные кавычки не будут ничего интерполировать, но двойные кавычки будут. Например: переменные, обратные метки, некоторые \экранированные символы и т. Д.
Заключение символов в одинарные кавычки ( ') сохраняет буквальное значение каждого символа в кавычках. Одиночная кавычка может отсутствовать между одинарными кавычками, даже если ей предшествует обратная косая черта.
Ограждающие символы в двойных кавычках ( ") сохраняет буквальное значение всех символов в кавычках, за исключением $, `, \и, когда раскрывание истории включено, !. Символы $и `сохраняют свое особое значение в двойных кавычках (см. Расширения оболочки ). Обратный слэш сохраняет свой особый смысл только тогда , когда следует один из следующих символов: $, `, ",\или перевод строки. В двойных кавычках удаляются обратные слэши, за которыми следует один из этих символов. Обратная косая черта предшествующих символов без специального значения остается неизменной. Двойная кавычка может быть заключена в двойные кавычки, если им предшествует обратный слеш. Если включено, расширение истории будет выполняться, если !в двойных кавычках не будет отображаться обратный слеш. Обратная косая черта, предшествующая символу !, не удаляется.
Что касается того, что когда вы используете git_promptgit, который они предлагают, они предлагают использовать его следующим образом PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ', git prompt , в соответствии с этим не должно работать. Есть ли что-то особенное в PS#переменных? или почему это работает, если он не выполняет интерполяцию.
Экиим
1
@ekiim Точный текст установлен (без изменений) в PS1. Попробуйте echo $PS1понять, что я имею в виду. Но PS1оценивается перед отображением (см. PROMPTINGРаздел на странице руководства bash). Чтобы проверить это, попробуйте PS1='$X'. У вас не будет подсказки. Затем запустите, X=fooи внезапно ваш запрос будет «foo» ( PS1был оценен, когда установлен вместо отображения, у вас все равно не будет запроса).
Адам Баткин
263
Общепринятый ответ велик. Я делаю таблицу, которая помогает в быстром понимании темы. Объяснение включает в себя как простую переменную, 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
---+-------------+-------------+--------------------------------------------------------------------
Принятый ответ говорит, в конце концов, The special parameters * and @ have special meaning when in double quotesтак как получится "*"результат *?
Андро
2
@ Karl-AnderoMere, потому что в этом случае они вообще не раскрываются как параметры. "$@"и "$*"расширения параметров. "@"и "*"нет.
Чарльз Даффи
@CharlesDuffy Спасибо, теперь это имеет смысл!
Андро
3
Номер 9 echo "\'", возвращает меня \'.
MaxGyver
@MaxGyver: спасибо за указание. Я обновил ответ.
Codeforester
233
Если вы ссылаетесь на то, что происходит, когда вы что-то выводите, одинарные кавычки будут буквально повторять то, что у вас есть между ними, в то время как двойные кавычки будут оценивать переменные между ними и выводить значение переменной.
Например, это
#!/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
Другие объяснили очень хорошо и просто хотят привести простые примеры.
Одинарные кавычки могут использоваться вокруг текста, чтобы оболочка не интерпретировала какие-либо специальные символы. Знаки доллара, пробелы, амперсанды, звездочки и другие специальные символы игнорируются, если заключены в одинарные кавычки.
$ 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
Обратные кавычки совершенно не похожи на одинарные или двойные. Вместо использования для предотвращения интерпретации специальных символов, обратные кавычки фактически заставляют выполнять команды, которые они заключают. После выполнения вложенных команд их вывод заменяется на обратные кавычки в исходной строке. Это будет понятнее с примером.
Существует четкое различие между использованием ' 'и " ".
Когда ' 'используется вокруг чего-либо, «преобразование или перевод» не выполняется. Он напечатан как есть.
С " "чем бы то ни было, оно «переводится или трансформируется» в свою ценность.
Под переводом / преобразованием я подразумеваю следующее: все, что находится в одинарных кавычках, не будет «переведено» в их значения. Они будут приняты, как они находятся внутри кавычек. Пример: a=23затем echo '$a'выдаст $aна стандартный вывод. Принимая во внимание, что echo "$a"будет производить 23на стандартной продукции.
Что вы подразумеваете под «переводом» или «трансформацией»?
Нико Хаасе
Этот ответ довольно запутанный, и он ничего не добавляет к существующим хорошим ответам.
Codeforester
2
По моему мнению, это был краткий краткий ответ без излишних слов, который мне было легко понять. Когда говорят перевод / преобразование, они имеют в виду, что двойные кавычки будут расширять переменную, а одинарные кавычки не будут расширять переменную.
B_e_n_n_y_
1
Да, это лучший ответ. Это должен быть принятый ответ.
Джейми Кирби
3
Поскольку это фактический ответ при работе с цитатами в 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))
Всегда не забывайте использовать $((..))без одинарных кавычек
Хотя он $((..))может использоваться с двойными кавычками, он не имеет смысла, так как в результате он не может содержать контент, который будет нуждаться в двойных кавычках. Просто убедитесь, что это не одиночные кавычки.
В некоторых особых случаях использования $((..))оператора внутри одной строки в кавычках может потребоваться интерполировать кавычки таким образом, чтобы оператор оставался без кавычек или в двойных кавычках. Например, рассмотрим случай, когда вы пытаетесь использовать оператор внутри curlоператора для передачи счетчика каждый раз, когда делается запрос, выполните
Чарльз Даффи делает хороший случай здесь для двойной процитировать , $((...))как хорошо. Это может быть «немного» параноиком и, скорее всего, маловероятно IFS=0, но это, конечно, не невозможно :)
PesaThe
Существует также устаревший $[[...]]синтаксис, но, возможно, вы были правы, забыв об этом.
Ответы:
Одинарные кавычки не будут ничего интерполировать, но двойные кавычки будут. Например: переменные, обратные метки, некоторые
\
экранированные символы и т. Д.Пример:
В руководстве по Bash сказано следующее:
источник
git_prompt
git, который они предлагают, они предлагают использовать его следующим образомPS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
, git prompt , в соответствии с этим не должно работать. Есть ли что-то особенное вPS#
переменных? или почему это работает, если он не выполняет интерполяцию.PS1
. Попробуйтеecho $PS1
понять, что я имею в виду. НоPS1
оценивается перед отображением (см.PROMPTING
Раздел на странице руководства bash). Чтобы проверить это, попробуйтеPS1='$X'
. У вас не будет подсказки. Затем запустите,X=foo
и внезапно ваш запрос будет «foo» (PS1
был оценен, когда установлен вместо отображения, у вас все равно не будет запроса).Общепринятый ответ велик. Я делаю таблицу, которая помогает в быстром понимании темы. Объяснение включает в себя как простую переменную,
a
так и индексированный массивarr
.Если мы установим
и затем
echo
выражение во втором столбце, мы получили бы результат / поведение, показанное в третьем столбце. Четвертый столбец объясняет поведение.Смотрите также:
$''
- Руководство по GNU Bash$""
- Руководство по GNU Bashисточник
The special parameters * and @ have special meaning when in double quotes
так как получится"*"
результат*
?"$@"
и"$*"
расширения параметров."@"
и"*"
нет.echo "\'"
, возвращает меня\'
.Если вы ссылаетесь на то, что происходит, когда вы что-то выводите, одинарные кавычки будут буквально повторять то, что у вас есть между ними, в то время как двойные кавычки будут оценивать переменные между ними и выводить значение переменной.
Например, это
даст это:
источник
Другие объяснили очень хорошо и просто хотят привести простые примеры.
Одинарные кавычки могут использоваться вокруг текста, чтобы оболочка не интерпретировала какие-либо специальные символы. Знаки доллара, пробелы, амперсанды, звездочки и другие специальные символы игнорируются, если заключены в одинарные кавычки.
Это даст это:
Единственное, что не может быть заключено в одинарные кавычки - это одинарные кавычки.
Двойные кавычки действуют аналогично одинарным, за исключением того, что двойные кавычки по-прежнему позволяют оболочке интерпретировать знаки доллара, обратные кавычки и обратные слэши. Уже известно, что обратные слэши препятствуют интерпретации одного специального символа. Это может быть полезно в двойных кавычках, если знак доллара необходимо использовать как текст, а не как переменную. Это также позволяет экранировать двойные кавычки, чтобы они не интерпретировались как конец строки в кавычках.
Это даст это:
Также можно заметить, что апостроф, который иначе интерпретируется как начало строки в кавычках, игнорируется в двойных кавычках. Переменные, однако, интерпретируются и заменяются их значениями в двойных кавычках.
Это даст это:
Обратные кавычки совершенно не похожи на одинарные или двойные. Вместо использования для предотвращения интерпретации специальных символов, обратные кавычки фактически заставляют выполнять команды, которые они заключают. После выполнения вложенных команд их вывод заменяется на обратные кавычки в исходной строке. Это будет понятнее с примером.
Это даст это:
источник
Существует четкое различие между использованием
' '
и" "
.Когда
' '
используется вокруг чего-либо, «преобразование или перевод» не выполняется. Он напечатан как есть.С
" "
чем бы то ни было, оно «переводится или трансформируется» в свою ценность.Под переводом / преобразованием я подразумеваю следующее: все, что находится в одинарных кавычках, не будет «переведено» в их значения. Они будут приняты, как они находятся внутри кавычек. Пример:
a=23
затемecho '$a'
выдаст$a
на стандартный вывод. Принимая во внимание, чтоecho "$a"
будет производить23
на стандартной продукции.источник
Поскольку это фактический ответ при работе с цитатами в
bash
, я добавлю еще один момент, пропущенный в ответах выше, при работе с арифметическими операторами в оболочке.bash
Оболочка поддерживает два способа сделать арифметическую операцию, которая определена с помощью встроенного вlet
команде и$((..))
оператора. Первое вычисляет арифметическое выражение, в то время как второе является скорее составным выражением.Важно понимать, что арифметическое выражение, используемое с
let
делением слов, раскрывает путь, как и любые другие команды оболочки. Так что правильное цитирование и экранирование должны быть сделаны.Смотрите этот пример при использовании
let
Использование одинарных кавычек здесь абсолютно нормально, так как здесь нет необходимости в расширении переменных, рассмотрим случай
с треском провалится, так как
$bar
нижние одинарные кавычки не будут расширяться и должны быть заключены в двойные кавычки какЭто должно быть одной из причин, которую
$((..))
следует всегда учитывать при использованииlet
. Потому что внутри него содержимое не подлежит расщеплению. Предыдущий пример использованияlet
может быть просто записан какВсегда не забывайте использовать
$((..))
без одинарных кавычекХотя он
$((..))
может использоваться с двойными кавычками, он не имеет смысла, так как в результате он не может содержать контент, который будет нуждаться в двойных кавычках. Просто убедитесь, что это не одиночные кавычки.В некоторых особых случаях использования
$((..))
оператора внутри одной строки в кавычках может потребоваться интерполировать кавычки таким образом, чтобы оператор оставался без кавычек или в двойных кавычках. Например, рассмотрим случай, когда вы пытаетесь использовать оператор внутриcurl
оператора для передачи счетчика каждый раз, когда делается запрос, выполнитеОбратите внимание на использование вложенных двойных кавычек внутри, без которых буквенная строка
$((reqcnt++))
передается вrequestCounter
поле.источник
$((...))
как хорошо. Это может быть «немного» параноиком и, скорее всего, маловероятноIFS=0
, но это, конечно, не невозможно :)$[[...]]
синтаксис, но, возможно, вы были правы, забыв об этом.