在Bash中,单引号('')和双引号(“”)之间有什么区别?


当前回答

如果你指的是当你回显某个东西时发生的事情,那么单引号将直接回显它们之间的内容,而双引号将计算它们之间的变量并输出变量的值。

例如,这个

#!/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 $ & * ; |.

唯一不能放在单引号内的是单引号。

双引号的作用类似于单引号,但双引号仍然允许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

如果你指的是当你回显某个东西时发生的事情,那么单引号将直接回显它们之间的内容,而双引号将计算它们之间的变量并输出变量的值。

例如,这个

#!/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 "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")

Bash手册有这样的说法:

3.1.2.2单项报价将字符括在单引号(')中会保留引号中每个字符的文字值。单引号不能出现在单引号之间,即使前面有反斜杠。3.1.2.3双引号将字符括在双引号(“)中会保留引号中所有字符的文字值,但启用历史扩展时,$、`、\和!除外。字符$和`在双引号中保留其特殊含义(请参阅Shell扩展)。反斜杠仅在后跟以下字符之一时保留其特殊意义:$、`,“、\或换行符。在双引号内,将删除后跟其中一个字符的反斜杠。没有特殊含义的字符前面的反斜杠将保持不变。双引号可以在双引号内加反斜杠。如果启用,将执行历史扩展,除非!出现在双引号中的字符使用反斜杠转义。前面的反斜杠!未删除。特殊参数*和@在双引号中时具有特殊含义(请参见Shell参数扩展)。

由于这是在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字段。

“”和“”的用法有明显区别。

当“”用于任何事物时,不会进行“转换或翻译”。它按原样打印。

“”,无论它围绕着什么,都被“翻译或转化”为它的价值。

通过翻译/转换,我的意思是:单引号内的任何内容都不会“转换”为其值。它们将被视为引号内的内容。示例:a=23,则echo“$a”将在标准输出上生成$a。而echo“$a”将在标准输出上产生23。