Разница между одинарными и двойными кавычками в Bash
В Bash, в чем разница между одинарными кавычками (''
) и двойными кавычками (""
)?
4 ответ(ов)
Если вы имеете в виду, что происходит, когда вы используете команду echo
, то одинарные кавычки просто выведут текст между ними без изменений, в то время как двойные кавычки оценят переменные и выведут их значения.
Например, следующий код:
#!/bin/sh
MYVAR=sometext
echo "двойные кавычки выведут вам $MYVAR"
echo 'одинарные кавычки выведут вам $MYVAR'
напечатает следующее:
двойные кавычки выведут вам sometext
одинарные кавычки выведут вам $MYVAR
Другие уже объяснили это очень хорошо, и я просто хочу предложить несколько простых примеров.
Одинарные кавычки используются для текстов, чтобы предотвратить интерпретацию специальных символов оболочкой. Символы, такие как доллар, пробелы, амперсанды, звездочки и другие специальные символы игнорируются, когда они заключены в одинарные кавычки.
echo 'Все возможные символы игнорируются в одинарных кавычках, такие как $ & * ; |.'
Это даст следующий вывод:
Все возможные символы игнорируются в одинарных кавычках, такие как $ & * ; |.
Единственное, что нельзя вставить в одинарные кавычки — это также одна одинарная кавычка.
Двойные кавычки действуют похоже на одинарные, но позволяют оболочке интерпретировать долларовые знаки, обратные кавычки и обратные слэши. Известно, что обратные слэши предотвращают интерпретацию одного специального символа. Это может быть полезным в двойных кавычках, если долларовый знак нужно использовать как текст, а не для переменной. Также это позволяет экранировать двойные кавычки, чтобы они не воспринимались как конец строки.
echo "Вот как мы можем использовать одинарные ' и двойные \" кавычки в двойных кавычках"
Это выдаст:
Вот как мы можем использовать одинарные ' и двойные " кавычки в двойных кавычках
Также стоит заметить, что апостроф, который в противном случае был бы интерпретирован как начало строки, игнорируется внутри двойных кавычек. Однако переменные интерпретируются и заменяются их значениями внутри двойных кавычек.
echo "Текущий Oracle SID это $ORACLE_SID"
Это даст:
Текущий Oracle SID это test
Обратные кавычки кардинально отличаются от одинарных и двойных. Вместо того чтобы предотвращать интерпретацию специальных символов, обратные кавычки фактически заставляют выполнять команды, которые они заключают. После выполнения включенных команд их вывод заменяет обратные кавычки в исходной строке. Это будет более понятно на примере.
today=`date '+%A, %B %d, %Y'`
echo $today
Это выдаст:
Monday, September 28, 2015
Поскольку это фактически является ответом на вопрос о работе с кавычками в 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
.
Существует четкое различие в использовании одинарных (' '
) и двойных (" "
) кавычек.
Когда используются одинарные кавычки, никакая "трансформация или преобразование" не происходит. Значение выводится именно так, как есть.
При использовании двойных кавычек содержимое внутри них "трансформируется или переводится" в соответствующее значение.
Под трансформацией/переводом я имею в виду следующее: все, что заключено в одинарные кавычки, не будет "переведено" в их значения. Оно будет восприниматься именно так, как написано в кавычках. Например, если у нас есть переменная a=23
, то команда echo '$a'
выведет на стандартный вывод $a
. В то время как команда echo "$a"
выведет 23
на стандартный вывод.
Как выводить команды оболочки по мере их выполнения
Назначение значений по умолчанию для переменных оболочки одной командой в bash
Как указать приватный SSH-ключ для выполнения команды shell в Git?
Как сделать паузу в shell-скрипте на одну секунду перед продолжением?
Как использовать 'grep' для непрерывного потока?