Bash中单引号和双引号的区别

在Bash中,单引号('')和双引号("")有什么区别?

372059 次浏览

单引号不会插入任何内容,但双引号会。例如:变量、反引号、某些\转义等。

示例:

$ echo "$(echo "upg")"upg$ echo '$(echo "upg")'$(echo "upg")

Bash手册是这样说的:

3.1.2.2单引号

用单引号括起字符(')保留引号中每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠。

3.1.2.3双引号

用双引号(")括起的字符将保留引号内所有字符的字面值,但$`\和启用历史扩展时的!除外。字符$`在双引号内保留其特殊含义(请参阅$3)。反斜杠仅在后面跟有以下字符之一时才保留其特殊含义:$`"\或换行符。在双引号内,后面跟有这些字符之一的反斜杠将被删除。没有特殊含义的反斜杠前面的字符将保持不变。双引号可以在双引号内用反斜杠引用。如果启用,将执行历史扩展,除非使用反斜杠转义出现在双引号中的!!之前的反斜杠不会删除。

特殊参数*@在双引号中具有特殊含义(参见外壳参数扩展)。

如果你指的是当你回显一些东西时会发生什么,单引号将从字面上回显它们之间的内容,而双引号将评估它们之间的变量并输出变量的值。

例如,这

#!/bin/shMYVAR=sometextecho "double quotes gives you $MYVAR"echo 'single quotes gives you $MYVAR'

将给出这个:

double quotes gives you sometextsingle quotes gives you $MYVAR

接受的答案很棒。我正在制作一个有助于快速理解主题的表格。解释涉及一个简单的变量a以及一个索引数组arr

如果我们设定

a=apple      # a simple variablearr=(apple)  # an indexed array with a single element

然后将第二列中的表达式echo,我们将得到第三列中显示的结果/行为。第四列解释了行为。

#表情结果评论
1"$a"apple变量在""内展开
2'$a'$a变量没有在''中展开
3"'$a'"'apple'''""中没有特殊含义
4'"$a"'"$a"""''中按字面意思处理
5'\''无效不能在''内转义';使用"'"$'\''(ANSI-C引用)
6"red$arocks"red$arocks不展开$a;使用${a}rocks保留$a
7"redapple$"redapple$$后跟没有变量名的计算结果为$
8'\"'\"\''中没有特殊含义
9"\'"\'\'""中解释,但对'没有意义
10"\"""\"""内部解释
11"*"*Glob在""''中不起作用
12"\t\n"\t\n\t\n""''中没有特殊含义;使用ANSI-C引用
13"`echo hi`"hi``$()""中求值(反引号保留在实际输出中)
14'`echo hi`'`echo hi```$()不在''中求值(反引号保留在实际输出中)
15'${arr[0]}'${arr[0]}''内部无法访问数组
16"${arr[0]}"apple数组访问在""内部工作
20"!cmd"cmd args扩展到匹配"cmd"的最新命令
21$'!cmd'!cmd历史扩展字符'!'在ANSI-C引号中被忽略

另见:

其他人解释得很好,我只想举一些简单的例子。

单引号可以在文本周围使用,以防止shell解释任何特殊字符。当包含在单引号中时,美元符号、空格、与号、星号和其他特殊字符都将被忽略。

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中的算术运算符时。

Bash shell支持两种进行算术运算的方法,一种由内置的let命令定义,另一种由$((..))运算符定义。前者计算算术表达式,而后者更像是复合语句。

重要的是要理解let使用的算术表达式经历了分词、路径名扩展,就像任何其他shell命令一样。因此需要进行适当的引用和转义。

使用let时请参阅此示例:

let 'foo = 2 + 1'echo $foo3

在这里使用单引号绝对没问题,因为这里不需要任何变量扩展。考虑一个案例

bar=1let '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 numberprintf '%d\n' $((1+1))2printf '%d\n' "$((1+1))"2

也许在某些特殊情况下,在单个加引号的字符串中使用$((..))运算符,您需要以运算符未加引号或双引号的方式插入引号。例如,考虑一个案例,当您在curl语句中绑定使用运算符以在每次发出请求时传递计数器时,请这样做

curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'

请注意内部使用了嵌套双引号,没有它,文字字符串$((reqcnt++))将传递给requestCounter字段。

人们需要一个最小的答案来开始,而不需要像我不得不花很多时间。

令人惊讶的是(对于那些寻找答案的人),以下是一个完整的命令:

$ echo '\'

其输出为:

\

令人惊讶的是,即使是bash的长期用户,反斜杠在单引号中也没有任何意义。其他任何东西也没有。