在 bash 中将变量值括在引号中与不将变量值括起来

在 bash 中将变量值括在引号中与不将变量值括起来

当我做这样的事情时:

x="hi echo hello"

或者

x='hi echo hello'

然后x将包含字符串hi echo hello

但是当我不使用引号时:

x=hi echo hello

然后x将包含字符串hi,并且命令echo hello将被执行。


但是,当变量的值仅由单个单词组成时,以下内容之间是否存在差异:

x="hi"
x='hi'
x=hi

答案1

仅当世界包含替代品时。

所以

x=$FRED

不同于:

x='$FRED'

答案2

不,无论是否加引号,普通字母和数字的含义都不会改变。

另外,正如中提到的这个答案,扩展后的分词或进行赋值时的文件名通配符都不会发生,因此通配符在该上下文中并不特殊,并且与大多数其他地方不同,您可以使用不带引号的变量而不调用拆分。 var1=*分配文字星号,并var2=$var1分配 的值var1,无论其中有任何 IFS 字符。

其他特殊字符还是比较特殊的:

  • 空白
  • $`用于扩展的反引号(如 @Julian 指出的)
  • 括号,用于数组赋值(如@cas所述)。如果放错位置,它们将导致语法错误
  • !用于历史扩展、<>|重定向、;结束&管道以及\转义其他字符的反斜杠。

所有这些都需要被引用或转义以防止它们具有特殊含义。

答案3

shell 做的第一件事就是分割线未引用的将空格(元字符)转换为标记。这与扩展后完成的分词不同,因为 IFS 值是不是用过的。用于初始标记分割的字符被固定为元字符。所有这些都会var包含Hello(有时是短暂的):

var=Hello echo World       # Space
var=Hello;echo World       # Semicolon
var=Hello   echo World     # Tab
var=Hello&echo World       # Ampersand

此外,对于此初始令牌分割,赋值的右侧被视为引用。
所有这些都是等价的:

var="Hello World"
var='Hello World'
var=Hello\ World

请注意,唯一的字符必须被引用的是空白。即使IFS被修改。

当然,在双引号内允许进行多种扩展:

var=~"/"       ;  var=~/         tilde  expansion (outside quotes)
var="$PWD"     ;  var=$PWD       parameter  and variable expansion
var="$(pwd)"   ;  var=$(pwd)     command substitution
var="$((2+3))" ;  var=$((2+3))   arithmetic expansion
var="!$"       ;  var=!$         history substitution

上面的所有对都是等价的(相同)。

没有任何这些对在单引号内(或带有一些反引号)的工作方式相同,例如:

var='$PWD'     ;  var=\$PWD

另外,这都是不是相等的:

var="( Hello World )"   ; var=( Hello World )

括号触发数组赋值


所以,所有这些都是等价的:

var=hi
var="hi"
var='hi'
var=\hi
var=h\i
var=\h\i

考虑到之前给出的特殊条件。

相关内容