[英]Why does echo “$@” not show the script name but explicit iteration does?
请考虑脚本foo.bash
#!/bin/env bash
echo "$@"
echo
for x in "${@:0:$# + 1}" ; do
echo "$x"
done
然后./foo.bash ab c
给出 output
a b c
./foo.bash
a
b
c
据我了解文档, @
持有位置 arguments,因此echo "$@"
的 output 对我来说很有意义。
但是为什么for
循环会打印脚本名称呢?
编辑:
我在 Windows 上使用 Git BASH, echo $BASH_VERSION
产生 4.4.23(1)-release
此行为特定于bash
4+。
按man bash
@
展开为位置参数,从一开始。 也就是说,"$@"
等价于"$1" "$2" "$3"
...
然而:
${parameter:offset:length}
Substring 扩展。 从 offset 指定的字符开始扩展到参数值的最大长度字符。 如果 parameter 是@
、以@
或*
为下标的索引数组或关联数组名称,则结果不同,如下所述。 如果省略长度,则扩展为参数值的 substring,从 offset 指定的字符开始并扩展到值的末尾。 长度和偏移量是算术表达式(参见下面的算术评估)。 如果 parameter 是@
,则结果是从offset
开始的length
位置参数。 如果 parameter 是由@
或*
下标的索引数组名称,则结果是以${parameter[offset]}
开头的数组的长度成员。
Substring 索引是从零开始的,除非使用位置参数,在这种情况下,索引默认从 1 开始。 如果
offset
为 0,并且使用了位置参数,则$0
将作为 list 的前缀。
因此,如果您使用:
"${@:0}"
这也将包括$0
但是如前所述:
"$@"
将从 position 一开始。
PS:请注意,在之前的bash
版本中,行为不同, "${@:0}"
不包括$0
。
这正是 Ksh 和 Zsh 所做的(并且子字符串/数组切片符号很可能源自 Ksh)。
$@
只给出位置参数而不是$0
的要点是它可以用于像for x in "$@"; do...
这样的循环中。 for x in "$@"; do...
(尽管您可以只使用for x do...
)或传递给其他命令,如在somecmd "$@"
中,可能在一些转移以修改列表之后。 在同一个列表中混合$0
很少有用。
但是在${@:0:n}
中,您也明确要求索引0
。 真的没有理由不给用户包含$0
的可能性,因为如果他们不想要它,他们可以使用$@
或${@:1}
代替。
对于常规的 arrays, ${array[0]}
是常规元素,因此自然包含在${array[@]}
和${array[@]:0}
中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.