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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:46:32  来源:igfitidea点击:

Bash array creation: ("$@") vs ($@)

linuxbashshell

提问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 $varwent 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 multiplewordsarg3- ie. the quotes preserve special characters after the variable has been expanded.

如果您没有用引号"multiple words arg3"将其括起来,则将进一步扩展为multiplewordsarg3- 即。引号在变量扩展后保留特殊字符。

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.

换句话说,当你没有用引号包围变量扩展时,变量扩展到的内容将被进一步扩展,在这种情况下,这将消除第三个参数周围的双引号。