Bash 中单引号和双引号的区别
在 Bash 中,单引号 (''
) 和双引号 (""
) 之间有什么区别?
In Bash, what are the differences between single quotes (''
) and double quotes (""
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
单引号不会插入任何内容,但双引号会插入任何内容。例如:变量、反引号、某些
\
转义符等。示例:
Bash 手册有这样的说法:
Single quotes won't interpolate anything, but double quotes will. For example: variables, backticks, certain
\
escapes, etc.Example:
The Bash manual has this to say:
接受的答案非常棒。我正在制作一个表格,有助于快速理解该主题。解释涉及一个简单的变量
a
以及一个索引数组arr
。如果我们设置
然后
echo
第二列中的表达式,我们将获得第三列中显示的结果/行为。第四列解释了该行为。"$a"
apple
""
内扩展'$a'
''
内部扩展"'$a'"
'apple'
' '
在""
内没有特殊含义'"$a"'
"$a"
""
在''
5'\''
''
内的'
;使用"'"
或$'\''
(ANSI-C 引用)"red$arocks"
red
$arocks
不会扩展$a
;使用${a}rocks
保存$a
"redapple$"
redapple$
$< /code> 后面没有变量名,计算结果为
$
'\"'
\"
\
没有特殊的''
"\'"
\'
\'
在""
内部解释,但对' 没有任何意义
"\""
"
\"
在""
11" *"
*
""
或''
"\t\n"
\t\n
\t< /code> 和
\n
在""
或''
中没有特殊含义,使用 ANSI-C 引用"`echo你好`"
你好
``
和$()
在""
内部求值(反引号保留在实际输出中)'`echo hi`'
`echo hi`
``
和$()
不会在''
内求值(反引号保留在实际输出中)'${arr[0]}'
${arr[0]}
''
内访问数组"$ {arr[0]}"
apple
""
内部工作$'$a\''
$a'
"$'\t'"
$'\t'
""
内部解释' !cmd'
!cmd
'!'
在''
内被忽略"!cmd"< /code>
cmd args
"cmd"
的命令$'!cmd'
!cmd
'!'
在 ANSI-C 引号内被忽略另请参阅:
$''
- GNU Bash 手册$""
进行区域设置翻译 - GNU Bash 手册The accepted answer is great. I am making a table that helps in quick comprehension of the topic. The explanation involves a simple variable
a
as well as an indexed arrayarr
.If we set
and then
echo
the expression in the second column, we would get the result / behavior shown in the third column. The fourth column explains the behavior."$a"
apple
""
'$a'
$a
''
"'$a'"
'apple'
''
has no special meaning inside""
'"$a"'
"$a"
""
is treated literally inside''
'\''
'
within''
; use"'"
or$'\''
(ANSI-C quoting)"red$arocks"
red
$arocks
does not expand$a
; use${a}rocks
to preserve$a
"redapple$"
redapple$
$
followed by no variable name evaluates to$
'\"'
\"
\
has no special meaning inside''
"\'"
\'
\'
is interpreted inside""
but has no significance for'
"\""
"
\"
is interpreted inside""
"*"
*
""
or''
"\t\n"
\t\n
\t
and\n
have no special meaning inside""
or''
; use ANSI-C quoting"`echo hi`"
hi
``
and$()
are evaluated inside""
(backquotes are retained in actual output)'`echo hi`'
`echo hi`
``
and$()
are not evaluated inside''
(backquotes are retained in actual output)'${arr[0]}'
${arr[0]}
''
"${arr[0]}"
apple
""
$'$a\''
$a'
"$'\t'"
$'\t'
""
'!cmd'
!cmd
'!'
is ignored inside''
"!cmd"
cmd args
"cmd"
$'!cmd'
!cmd
'!'
is ignored inside ANSI-C quotesSee also:
$''
- GNU Bash Manual$""
- GNU Bash Manual如果您指的是回显某些内容时会发生什么,那么单引号实际上会回显它们之间的内容,而双引号将评估它们之间的变量并输出变量的值。
例如,这
将给出:
If you're referring to what happens when you echo something, the single quotes will literally echo what you have between them, while the double quotes will evaluate variables between them and output the value of the variable.
For example, this
will give this:
其他人解释得很好,我只想用简单的例子来说明。
可以在文本周围使用单引号,以防止 shell 解释任何特殊字符。当用单引号括起来时,美元符号、空格、& 符号、星号和其他特殊字符都将被忽略。
它将给出:
唯一不能放在单引号内的是单引号。
双引号的作用与单引号类似,但双引号仍然允许 shell 解释美元符号、反引号和反斜杠。众所周知,反斜杠会阻止解释单个特殊字符。如果需要将美元符号用作文本而不是变量,这在双引号内非常有用。它还允许对双引号进行转义,因此它们不会被解释为带引号的字符串的结尾。
它会给出这样的结果:
还可能注意到,撇号(否则将被解释为带引号的字符串的开头)在双引号内被忽略。然而,变量会被解释并替换为双引号内的值。
它将给出:
反引号完全不同于单引号或双引号。反引号实际上不是用来阻止解释特殊字符,而是强制执行它们所包含的命令。执行包含的命令后,它们的输出将替换原始行中的反引号。通过一个例子会更清楚。
它将给出:
Others explained it very well, and I just want to give something with simple examples.
Single quotes can be used around text to prevent the shell from interpreting any special characters. Dollar signs, spaces, ampersands, asterisks and other special characters are all ignored when enclosed within single quotes.
It will give this:
The only thing that cannot be put within single quotes is a single quote.
Double quotes act similarly to single quotes, except double quotes still allow the shell to interpret dollar signs, back quotes and backslashes. It is already known that backslashes prevent a single special character from being interpreted. This can be useful within double quotes if a dollar sign needs to be used as text instead of for a variable. It also allows double quotes to be escaped so they are not interpreted as the end of a quoted string.
It will give this:
It may also be noticed that the apostrophe, which would otherwise be interpreted as the beginning of a quoted string, is ignored within double quotes. Variables, however, are interpreted and substituted with their values within double quotes.
It will give this:
Back quotes are wholly unlike single or double quotes. Instead of being used to prevent the interpretation of special characters, back quotes actually force the execution of the commands they enclose. After the enclosed commands are executed, their output is substituted in place of the back quotes in the original line. This will be clearer with an example.
It will give this:
由于这是在 Bash 中处理引号时事实上的答案,因此在处理 shell 中的算术运算符时,我将补充上面答案中遗漏的另一点。
Bash shell 支持两种进行算术运算的方法,一种是通过内置的
let
命令定义的,另一种是通过$((..))
运算符定义的。前者计算算术表达式,而后者更多的是复合语句。重要的是要理解,与
let
一起使用的算术表达式会像任何其他 shell 命令一样经历分词、路径名扩展。因此需要进行正确的引用和转义。使用
let
时请参阅此示例:这里使用单引号绝对没问题,因为这里不需要变量扩展。考虑这样一种情况,
它会惨败,因为单引号下的
$bar
不会扩展,需要双引号,因为这应该是原因之一,应始终考虑使用
$((..))
而不是使用let
。因为在它内部,内容不会受到分词的影响。前面使用let
的示例可以简单地写为始终记住使用不带单引号的
$((..))
尽管
$((..))
可以与双引号一起使用,但它没有任何用途,因为它不能包含需要双引号的内容。只要确保它不是单引号即可。也许在某些特殊情况下,在单引号字符串中使用
$((..))
运算符时,您需要以运算符不带引号或位于双引号下的方式插入引号。例如,考虑一种情况,当您试图在每次发出请求时使用curl
语句内的运算符来传递计数器时,请注意内部嵌套双引号的使用,如果没有它,则文字字符串
$((reqcnt++))
被传递到requestCounter
字段。Since this is the de facto answer when dealing with quotes in Bash, I'll add upon one more point missed in the answers above, when dealing with the arithmetic operators in the shell.
The Bash shell supports two ways to do arithmetic operation, one defined by the built-in
let
command and the other the$((..))
operator. The former evaluates an arithmetic expression while the latter is more of a compound statement.It is important to understand that the arithmetic expression used with
let
undergoes word-splitting, pathname expansion just like any other shell commands. So proper quoting and escaping need to be done.See this example when using
let
:Using single quotes here is absolutely fine here, as there isn't any need for variable expansions here. Consider a case of
It would fail miserably, as the
$bar
under single quotes would not expand and needs to be double-quoted asThis should be one of the reasons, the
$((..))
should always be considered over usinglet
. Because inside it, the contents aren't subject to word-splitting. The previous example usinglet
can be simply written asAlways remember to use
$((..))
without single quotesThough the
$((..))
can be used with double quotes, there isn't any purpose to it as the result of it cannot contain content that would need the double quote. Just ensure it is not single quoted.Maybe in some special cases of using the
$((..))
operator inside a single quoted string, you need to interpolate quotes in a way that the operator either is left unquoted or under double quotes. E.g., consider a case, when you are tying to use the operator inside acurl
statement to pass a counter every time a request is made, doNotice the use of nested double quotes inside, without which the literal string
$((reqcnt++))
is passed to therequestCounter
field.' '
和" "
的用法有明显区别。当
' '
用于任何内容时,不会进行“转换或翻译”。它按原样打印。对于
" "
,无论它包围什么,都会被“翻译或转换”为其值。我所说的翻译/转换是指以下内容:
单引号内的任何内容都不会“转换”为其值。它们将被视为在引号内。示例:
a=23
,则echo '$a'
将在标准输出上生成$a
。而echo "$a"
将在标准输出上生成23
。There is a clear distinction between the usage of
' '
and" "
.When
' '
is used around anything, there is no "transformation or translation" done. It is printed as it is.With
" "
, whatever it surrounds, is "translated or transformed" into its value.By translation/ transformation I mean the following:
Anything within the single quotes will not be "translated" to their values. They will be taken as they are inside quotes. Example:
a=23
, thenecho '$a'
will produce$a
on standard output. Whereasecho "$a"
will produce23
on standard output.人们需要一个最小的答案才能开始工作,而不必像我一样花费大量时间。
令人惊讶的是(对于那些寻找答案的人来说),下面是一个完整的命令:
其输出是:
令人惊讶的是,即使是 bash 的长期用户,反斜杠在单引号内也没有任何意义。也没有其他任何事情。
A minimal answer is needed for people to get going without spending a lot of time as I had to.
The following is, surprisingly (to those looking for an answer), a complete command:
whose output is:
Backslashes, surprisingly to even long-time users of bash, do not have any meaning inside single quotes. Nor does anything else.