Ответы:
Одинарные кавычки не будут ничего интерполировать, но двойные кавычки будут. Например: переменные, обратные метки, некоторые \
экранированные символы и т. Д.
Пример:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
В руководстве по 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
.
Если мы установим
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
так как получится "*"
результат *
?
"$@"
и "$*"
расширения параметров. "@"
и "*"
нет.
echo "\'"
, возвращает меня \'
.
Если вы ссылаетесь на то, что происходит, когда вы что-то выводите, одинарные кавычки будут буквально повторять то, что у вас есть между ними, в то время как двойные кавычки будут оценивать переменные между ними и выводить значение переменной.
Например, это
#!/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
Обратные кавычки совершенно не похожи на одинарные или двойные. Вместо использования для предотвращения интерпретации специальных символов, обратные кавычки фактически заставляют выполнять команды, которые они заключают. После выполнения вложенных команд их вывод заменяется на обратные кавычки в исходной строке. Это будет понятнее с примером.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Это даст это:
Monday, September 28, 2015
Существует четкое различие между использованием ' '
и " "
.
Когда ' '
используется вокруг чего-либо, «преобразование или перевод» не выполняется. Он напечатан как есть.
С " "
чем бы то ни было, оно «переводится или трансформируется» в свою ценность.
Под переводом / преобразованием я подразумеваю следующее: все, что находится в одинарных кавычках, не будет «переведено» в их значения. Они будут приняты, как они находятся внутри кавычек. Пример: a=23
затем echo '$a'
выдаст $a
на стандартный вывод. Принимая во внимание, что echo "$a"
будет производить 23
на стандартной продукции.
Поскольку это фактический ответ при работе с цитатами в 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
поле.
$((...))
как хорошо. Это может быть «немного» параноиком и, скорее всего, маловероятно IFS=0
, но это, конечно, не невозможно :)
$[[...]]
синтаксис, но, возможно, вы были правы, забыв об этом.