我正在运行一个带有:./some_script arg1 arg2 "multiple words arg3" arg4
的脚本。我想将参数($@
)分解成一个数组。这个片段只适用于没有空格的参数:
arr=($@)
如果我想将正确的参数存储到数组中,我必须使用:
arr=("$@")
为什么我要在$@
中加引号?
我认为这与参数扩展和特殊参数有关,但我认为我没有很好地理解。
在shell中,每当引用变量(包括$@
等特殊参数)时不使用双引号,该值在展开后会经过分词和通配符展开。例如:
$ var="FOO * BAR"
$ printf "%sn" "$var"
FOO * BAR
$ printf "%sn" $var
FOO
Desktop
Documents
Downloads
Library
Movies
Music
Pictures
Public
BAR
在第二种情况下,变量值"FOO*BAR"被拆分为单独的单词("FOO"、"*"one_answers"BAR"),然后"*"被扩展为匹配文件的列表。这就是为什么您几乎总是希望将变量引用放在双引号中。
同样的事情也适用于$@
——如果它不在双引号中,它会被扩展到参数列表中,然后每个参数都会像$var
一样进行分词和通配符扩展。如果是双引号,则参数值不会受到干扰。
顺便说一句,还有另一种方法可以获得参数:$*
。这与$@
的不同之处在于,它将所有参数值用空格粘在一起(而$@
将每个参数保持为一个单独的单词)。在双引号中,"$*"
给出一个由所有参数组成的单词。在没有双引号的情况下,$*
将所有参数粘在一起,然后重新拆分它们(可能在相同的位置,也可能不是),并进行通配符扩展。可能不是你想要的。
如果不用引号括起来,"multiple words arg3"
将进一步扩展为multiple
words
arg3
,即引号在变量展开后保留特殊字符。
换句话说,当你不用引号包围变量展开时,变量展开到的内容将被进一步展开,在这种情况下,这将消除第三个参数周围的双引号。