为什么$ @从工作在bash大多数其他变量有什么不同?

问题描述:

的$ @变量似乎维持围绕它的参数引用以便,例如:

The $@ variable seems to maintain quoting around its arguments so that, for example:

$ function foo { for i in "$@"; do echo $i; done }
$ foo herp "hello world" derp
herp
hello world
derp

我也知道bash的阵列,以同样的方式:

I am also aware that bash arrays, work the same way:

$ a=(herp "hello world" derp)
$ for i in "${a[@]}"; do echo $i; done
herp
hello world
derp

什么是实际发生的事情与这样的变量?特别是当我添加了一些报价,如鸭子$ {A [@]}鹅。如果它不是空格分隔是什么呢?

What is actually going on with variables like this? Particularly when I add something to the quote like "duck ${a[@]} goose". If its not space separated what is it?

通常,在击双引号的意思是使引号之间的一切标志着一个字,即使它有它分隔符。但是,正如你已经注意到了, $ @ 行为不同,当它的双引号的。这实际上是一个解析黑客可以追溯到猛砸的predecessor,Bourne shell的,而这种特殊的行为仅适用于这个特定的变量。

Usually, double quotation marks in Bash mean "make everything between the quotation marks one word, even if it has separators in it." But as you've noticed, $@ behaves differently when it's within double quotes. This is actually a parsing hack that dates back to Bash's predecessor, the Bourne shell, and this special behavior applies only to this particular variable.

如果没有这个技巧(我用这个词,因为它似乎从语言的角度不一致,虽然这是非常有用的),这将是困难的shell脚本,沿其阵列的参数传递给想要同样的论点一些其他的命令。其中的一些参数可能有空格他们,但它会如何将它们传递到另一个命令没有外壳要么一起混为一谈它们作为一个大的词或重新分析列表,并分裂有空白的论点?

Without this hack (I use the term because it seems inconsistent from a language perspective, although it's very useful), it would be difficult for a shell script to pass along its array of arguments to some other command that wants the same arguments. Some of those arguments might have spaces in them, but how would it pass them to another command without the shell either lumping them together as one big word or reparsing the list and splitting the arguments that have whitespace?

那么,你可以传递参数数组,和Bourne shell实际上只有通过 $ @ psented一个阵列,再$ P $,元素数为 $#,其元素是 $ 1 $ 2 等中,所谓的位置参数。

Well, you could pass an array of arguments, and the Bourne shell really only has one array, represented by $@, whose number of elements is $# and whose elements are $1, $2, etc, the so-called positional parameters.

一个例子。假设你在当前目录下,命名为三个文件有一个两个 thuh稀土(第三个文件的名称中有空格)。可以初始化阵列(也就是说,你可以设置位置参数)是文件的名称在当前目录是这样的:

An example. Suppose you have three files in the current directory, named one, two, and thuh ree (the third file has a space in the name). You can initialize the array (that is, you can set the positional parameters) to be the names of the files in the current directory like this:

set -- *

现在的 $ @ 数组保存文件的名称,而这个循环:

Now the $@ array holds the names of the files, and this loop:

for FILE in "$@"; do
    echo "$FILE"
done

会产生这样的输出:

will produce this output:

one
two
thuh ree

由于1 $ =一,$ 2 =两节和$ 3 =thuh稀土元素和$ @离开元素不变。谢谢你,黑客解析。如果您离开了周围的 $ @ 引号,shell将扁平化和重新解析数组,所以你会得到这样的输出:

because $1 = "one", $2 = "two", and $3 = "thuh ree" and "$@" leaves the elements intact. Thank you, parsing hack. If you leave off the quotation marks around $@, the shell will flatten and re-parse the array, so you'll get this output:

one
two
thuh
ree

在伯恩,这种行为并不适用于其他变量,这是不数组。但是的的也让你做其他的阵列,它甚至可以让你套用老的解析砍他们,使用特殊的$ {arrayName中的[@]}语法,其在符号感觉几乎就像一个眼色伯恩先生。

In Bourne, this behavior does not apply to other variables, which aren't arrays. But Bash does let you make other arrays, and it even lets you apply the old parsing hack to them, using the special "${ARRAYNAME[@]}" syntax, whose at-sign feels almost like a wink to Mr. Bourne.

哦,你的最后一个例子,应该壳做pre $ @帖子其中的展开一个字内发生?击preserve数组的最新版本,也prePEND前 $ @ 文本第一个数组元素和最后一个元素之后的文本追加:

Oh, and about your last example, what should the shell do with "pre $@ post" where the expansion occurs within a word? Recent versions of Bash preserve the array and also prepend the text before the $@ to the first array element and append the text after to the last element:

pre one
two
thuh
ree post