提问人:jrdioko 提问时间:7/15/2011 最后编辑:Timur Shtatlandjrdioko 更新时间:9/17/2022 访问量:420251
Bash 中单引号和双引号的区别
Difference between single and double quotes in Bash
答:
单引号不会插入任何内容,但双引号会。例如:变量、反引号、某些转义符等。\
例:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Bash 手册是这样说的:
将字符括在单引号 () 中可保留引号中每个字符的文本值。单引号之间不得出现单引号,即使前面有反斜杠也是如此。
'
将字符括在双引号 () 中将保留引号内所有字符的文本值,但 、 、 和 除外,当启用历史记录扩展时,。字符和在双引号内保留其特殊含义(请参见 Shell 扩展)。仅当后跟以下字符之一时,反斜杠才保留其特殊含义:、、、或换行符。在双引号内,将删除后跟其中一个字符的反斜杠。没有特殊含义的字符前面的反斜杠保持不变。双引号可以在双引号内引用,方法是在它前面加上反斜杠。如果启用,将执行历史记录扩展,除非使用反斜杠对出现在双引号中的出现进行转义。前面的反斜杠不会被删除。
"
$
`
\
!
$
`
$
`
"
\
!
!
特殊参数 和 在双引号中具有特殊含义(请参阅 Shell 参数扩展)。
*
@
评论
git_prompt
PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
PS#
PS1
echo $PS1
PS1
PROMPTING
PS1='$X'
X=foo
PS1
$ name='O'Hara'
$ name='O'\''Hara'
'
'\''
如果你指的是当你回显某物时会发生什么,单引号将从字面上回显你之间的东西,而双引号将评估它们之间的变量并输出变量的值。
例如,这个
#!/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
然后是第二列中的表达式,我们将得到第三列中显示的结果/行为。第四列解释该行为。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$ |
$ 后跟 no variable name 的计算结果为$ |
8 | '\"' |
\" |
\ 里面没有特别的意义'' |
9 | "\'" |
\' |
\' 在里面被解释,但对"" ' |
10 | "\"" |
" |
\" 在里面解释"" |
11 | "*" |
* |
glob 在内部不起作用或"" '' |
12 | "\t\n" |
\t\n |
\t 并且内部没有特殊含义或;使用 ANSI-C 引号\n "" '' |
13 | "`echo hi`" |
hi |
`` 并在内部进行评估(反引号保留在实际输出中)$() "" |
14 | '`echo hi`' |
`echo hi` |
`` 并且不会在内部进行评估(反引号保留在实际输出中)$() '' |
15 | '${arr[0]}' |
${arr[0]} |
内部无法访问阵列'' |
16 | "${arr[0]}" |
apple |
阵列访问在内部工作"" |
17 | $'$a\'' |
$a' |
单引号可以在 ANSI-C 引号中转义 |
18 | "$'\t'" |
$'\t' |
ANSI-C 引用内部不进行解释"" |
19 | '!cmd' |
!cmd |
历史扩展字符在内部被忽略'!' '' |
20 | "!cmd" |
cmd args |
展开到最新的命令匹配"cmd" |
21 | $'!cmd' |
!cmd |
ANSI-C 引号内的历史扩展字符被忽略'!' |
另请参阅:
评论
The special parameters * and @ have special meaning when in double quotes
"*"
*
"$@"
"$*"
"@"
"*"
echo $a
echo ${a[0]}
event not found
其他人解释得很好,我只想举一些简单的例子。
可以在文本两边使用单引号,以防止 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
评论
The only thing that cannot be put within single quotes is a single quote
和 的用法之间有明显的区别。' '
" "
当在任何东西周围使用时,没有完成“转换或翻译”。它按原样打印。' '
无论它围绕着什么,都会被“翻译或转化”成它的价值。" "
通过翻译/转换,我的意思是:
单引号内的任何内容都不会“翻译”为它们的值。它们将被当作内部引号。示例: ,然后将在标准输出上生成。而将在标准输出上产生。a=23
echo '$a'
$a
echo "$a"
23
评论
'foo $bar baz'
foo $bar baz
"foo $bar baz"
bar
foo
baz
由于这是在 Bash 中处理引号时事实上的答案,因此在处理 shell 中的算术运算符时,我将补充上面答案中遗漏的另一点。
Bash shell 支持两种算术运算方式,一种由内置命令定义,另一种由运算符定义。前者计算算术表达式,而后者更像是复合语句。let
$((..))
重要的是要了解,与任何其他 shell 命令一样,使用的算术表达式会经历分词、路径名扩展。因此,需要进行适当的引用和转义。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
评论
$((...))
IFS=0
$[[...]]
人们需要一个最低限度的答案,而不必像我一样花费大量时间。
令人惊讶的是(对于那些寻找答案的人来说),这是一个完整的命令:
$ echo '\'
其输出为:
\
令人惊讶的是,即使是 bash 的长期用户,反斜杠在单引号内没有任何意义。其他任何事情也没有。
评论
sh
ash
dash
ksh
zsh