繁体   English   中英

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

[英]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.

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