在Bash中,单引号('')和双引号(“”)之间有什么区别?
单引号不会插入任何内容,但双引号会插入。例如:变量、倒勾、某些\转义等。
例子:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Bash手册有这样的说法:
3.1.2.2单项报价将字符括在单引号(')中会保留引号中每个字符的文字值。单引号不能出现在单引号之间,即使前面有反斜杠。3.1.2.3双引号将字符括在双引号(“)中会保留引号中所有字符的文字值,但启用历史扩展时,$、`、\和!除外。字符$和`在双引号中保留其特殊含义(请参阅Shell扩展)。反斜杠仅在后跟以下字符之一时保留其特殊意义:$、`,“、\或换行符。在双引号内,将删除后跟其中一个字符的反斜杠。没有特殊含义的字符前面的反斜杠将保持不变。双引号可以在双引号内加反斜杠。如果启用,将执行历史扩展,除非!出现在双引号中的字符使用反斜杠转义。前面的反斜杠!未删除。特殊参数*和@在双引号中时具有特殊含义(请参见Shell参数扩展)。
如果你指的是当你回显某个东西时发生的事情,那么单引号将直接回显它们之间的内容,而双引号将计算它们之间的变量并输出变量的值。
例如,这个
#!/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
公认的答案很好。我正在制作一张有助于快速理解主题的表格。解释涉及一个简单变量a以及一个索引数组arr。
如果我们设置
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
然后在第二列中回显表达式,我们将得到第三列中显示的结果/行为。第四列解释了行为。
# | 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 "" (backquotes are retained in actual output) |
14 | '`echo hi`' |
`echo hi` |
`` and $() are not evaluated inside '' (backquotes are retained in actual output) |
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 |
另请参见:
ANSI-C引用$''-GNU Bash手册带有$“”的本地化翻译-GNU Bash手册报价的三点公式
其他人解释得很好,我只想举一些简单的例子。
可以在文本周围使用单引号,以防止外壳解释任何特殊字符。美元符号、空格、与符号、星号和其他特殊字符都会在单引号中被忽略。
echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
它将提供:
All sorts of things are ignored in single quotes, like $ & * ; |.
唯一不能放在单引号内的是单引号。
双引号的作用类似于单引号,但双引号仍然允许shell解释美元符号、反引号和反斜杠。众所周知,反斜杠阻止解释单个特殊字符。如果需要将美元符号用作文本而不是变量,这在双引号中非常有用。它还允许转义双引号,以便它们不会被解释为带引号字符串的结尾。
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中处理引号时事实上的答案,所以我将在处理shell中的算术运算符时补充上面答案中缺少的一点。
Bashshell支持两种进行算术运算的方法,一种由内置let命令定义,另一种由$((..))运算符定义。前者计算的是一个算术表达式,后者更像是一个复合语句。
重要的是要理解,与let一起使用的算术表达式会像其他shell命令一样经历单词分割、路径名扩展。因此,需要进行适当的引用和转义。
使用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字段。
人们需要一个最低限度的答案,不用像我那样花很多时间就可以开始工作。
令人惊讶的是(对于那些寻找答案的人来说),以下是一个完整的命令:
$ echo '\'
其输出为:
\
即使是bash的长期用户也感到惊讶的是,反斜杠在单引号中没有任何含义。其他也没有。