简体   繁体   English

为什么 echo "$@" 不显示脚本名称,但显式迭代却显示?

[英]Why does echo “$@” not show the script name but explicit iteration does?

Please consider the script foo.bash请考虑脚本foo.bash

#!/bin/env bash

echo "$@"
echo

for x in "${@:0:$# + 1}" ; do
    echo "$x"
done

Then ./foo.bash ab c gives the output然后./foo.bash ab c给出 output

a b c

./foo.bash
a
b
c

As far as I understand the documentation, @ holds the positional arguments, so the output of echo "$@" makes sense to me.据我了解文档, @持有位置 arguments,因此echo "$@"的 output 对我来说很有意义。

But why does the for loop print the script name?但是为什么for循环会打印脚本名称呢?

edit:编辑:

I'm using Git BASH on Windows, echo $BASH_VERSION yields 4.4.23(1)-release我在 Windows 上使用 Git BASH, echo $BASH_VERSION产生 4.4.23(1)-release

This behavior is specific to bash ver 4+.此行为特定于bash 4+。

As per man bashman bash

@ Expands to the positional parameters, starting from one. @展开为位置参数,从一开始。 That is, "$@" is equivalent to "$1" "$2" "$3" ...也就是说, "$@"等价于"$1" "$2" "$3" ...

However:然而:

${parameter:offset:length} Substring Expansion. ${parameter:offset:length} Substring 扩展。 Expands to up to length characters of the value of parameter starting at the character specified by offset.从 offset 指定的字符开始扩展到参数值的最大长度字符。 If parameter is @ , an indexed array subscripted by @ or * , or an associative array name, the results differ as described below.如果 parameter 是@ 、以@*为下标的索引数组或关联数组名称,则结果不同,如下所述。 If length is omitted, expands to the substring of the value of parameter starting at the character specified by offset and extending to the end of the value.如果省略长度,则扩展为参数值的 substring,从 offset 指定的字符开始并扩展到值的末尾。 length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below).长度和偏移量是算术表达式(参见下面的算术评估)。 If parameter is @ , the result is length positional parameters beginning at offset .如果 parameter 是@ ,则结果是从offset开始的length位置参数 If parameter is an indexed array name subscripted by @ or * , the result is the length members of the array beginning with ${parameter[offset]} .如果 parameter 是由@*下标的索引数组名称,则结果是以${parameter[offset]}开头的数组的长度成员。

Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default. Substring 索引是从零开始的,除非使用位置参数,在这种情况下,索引默认从 1 开始。 If offset is 0, and the positional parameters are used, $0 is prefixed to the list .如果offset为 0,并且使用了位置参数,则$0将作为 list 的前缀

So if you use:因此,如果您使用:

"${@:0}"

That will also include $0这也将包括$0

however as mentioned earlier:但是如前所述:

"$@"

will start from position one.将从 position 一开始。

PS: Note that in previous bash versions, behavior is different and "${@:0}" won't include $0 . PS:请注意,在之前的bash版本中,行为不同, "${@:0}"不包括$0

This is exactly what Ksh and Zsh also do (and the substring/array slice notation is likely to originate from Ksh).这正是 Ksh 和 Zsh 所做的(并且子字符串/数组切片符号很可能源自 Ksh)。

The point of $@ only giving the positional parameters and not $0 , is that it can be used in loops like for x in "$@"; do... $@只给出位置参数而不是$0的要点是它可以用于像for x in "$@"; do...这样的循环中。 for x in "$@"; do... (though you could just use for x do... ) or passed to other commands, as in somecmd "$@" , possibly after some shifting to modify the list. for x in "$@"; do... (尽管您可以只使用for x do... )或传递给其他命令,如在somecmd "$@"中,可能在一些转移以修改列表之后。 Mixing $0 in the same list is very rarely useful.在同一个列表中混合$0很少有用。

But in ${@:0:n} , you explicitly ask for index 0 , too.但是在${@:0:n}中,您也明确要求索引0 There's really no reason not to give the user the possibility of including $0 , since if they don't want it, they could use $@ or ${@:1} instead.真的没有理由给用户包含$0的可能性,因为如果他们不想要它,他们可以使用$@${@:1}代替。

With regular arrays, ${array[0]} is a regular element, so is naturally included in both ${array[@]} and ${array[@]:0} .对于常规的 arrays, ${array[0]}是常规元素,因此自然包含在${array[@]}${array[@]:0}中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM