Bash 数组创建:("$@") vs ($@)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22131114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash array creation: ("$@") vs ($@)
提问by Roxana
I am running a script with: ./some_script arg1 arg2 "multiple words arg3" arg4
. I want to explode arguments ($@
) into an array. This snippet works just for arguments without spaces:
我运行一个脚本:./some_script arg1 arg2 "multiple words arg3" arg4
。我想将参数 ( $@
) 分解成一个数组。此代码段仅适用于没有空格的参数:
arr=($@)
If I want to store the correct arguments into array I must use:
如果我想将正确的参数存储到数组中,我必须使用:
arr=("$@")
Why should I enclose $@
in quotes?
为什么我应该$@
用引号引起来?
I think this has something to do with parameter expansion and special parameters, but I don't think I got it well.
我认为这与参数扩展和特殊参数有关,但我认为我做得不好。
采纳答案by Gordon Davisson
In the shell, whenever a variable (including special parameters like $@
) in referenced without double-quotes, the value goes through word splitting and wildcard expansion after it's expanded. For example:
在shell中,每当一个变量(包括特殊参数,如$@
)不带双引号引用时,该值在扩展后会经历分词和通配符扩展。例如:
$ var="FOO * BAR"
$ printf "%s\n" "$var"
FOO * BAR
$ printf "%s\n" $var
FOO
Desktop
Documents
Downloads
Library
Movies
Music
Pictures
Public
BAR
In the second case, the variable value "FOO * BAR" got split into separate words ("FOO", "*", and "BAR"), and then the "*" was expanded into a list of matching files. This is why you almost always want to put variable references in double-quotes.
在第二种情况下,变量值“FOO * BAR”被拆分为单独的词(“FOO”、“*”和“BAR”),然后将“*”扩展为匹配文件的列表。这就是为什么您几乎总是希望将变量引用放在双引号中。
The same thing applies to $@
-- if it's not in double-quotes, it's expanded into the list of parameters and then each one of them is subjected to that same word splitting and wildcard expansion that $var
went through above. If it's in double-quotes, the parameter values are left unmolested.
同样的事情适用于$@
- 如果它不是双引号,它会扩展到参数列表中,然后每个参数都受到与上面相同的分词和通配符扩展$var
。如果是双引号,则参数值不会受到干扰。
BTW, there is another way to get the parameters: $*
. This differs from $@
in that it sticks all of the parameter values together with spaces between them (while $@
maintains each parameter as a separate word). In double-quotes, "$*"
gives a single word consisting of all parameters. Without double-quotes, $*
sticks all the parameters together, then re-splits them (maybe at the same places, maybe not), and does wildcard expansion. Probably not what you wanted.
顺便说一句,还有另一种获取参数的方法:$*
. 这与$@
它的不同之处在于它将所有参数值粘在一起并在它们之间使用空格(同时$@
将每个参数保持为一个单独的词)。在双引号中,"$*"
给出一个包含所有参数的单词。没有双引号,将$*
所有参数粘在一起,然后重新拆分它们(可能在相同的地方,也可能不在),并进行通配符扩展。可能不是你想要的。
回答by Gordon Davisson
If you didn't surround it with quotes, "multiple words arg3"
would be further expanded to multiple
words
arg3
- ie. the quotes preserve special characters after the variable has been expanded.
如果您没有用引号"multiple words arg3"
将其括起来,则将进一步扩展为multiple
words
arg3
- 即。引号在变量扩展后保留特殊字符。
In other words, when you don't surround a variable expansion with quotes, what the variable expands to will further be expanded, which would in this case eliminate the double quotes around the third argument.
换句话说,当你没有用引号包围变量扩展时,变量扩展到的内容将被进一步扩展,在这种情况下,这将消除第三个参数周围的双引号。