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

请考虑脚本 foo.bash

#!/bin/env bash

echo "$@"
echo

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

然后./foo.bash a b c给出输出

a b c

./foo.bash
a
b
c

据我了解文档,@保存位置参数,所以输出echo "$@"对我来说很有意义。

但是为什么for循环会打印脚本名称?

编辑:

我在 Windows 上使用 Git BASH,echo $BASH_VERSION产生 4.4.23(1)-release

回答

此行为特定于版本bash4+。

按照 man bash

@ 扩展到位置参数,从 1 开始。也就是说,"$@"相当于"$1" "$2" "$3"...

然而:

${parameter:offset:length}
子串扩展。从 offset 指定的字符开始,最多扩展到参数值的 length 个字符。 如果参数是@、下标为@或的索引数组*或关联数组名称,则结果不同,如下所述。如果省略length,则扩展为参数值的子字符串,从offset 指定的字符开始,一直延伸到值的末尾。length 和 offset 是算术表达式(参见下面的 ARITHMETIC EVALUATION)。
如果参数是@,则结果是length从 开始的位置参数offset。如果参数是下标为@或的索引数组名称*,结果是以 开头的数组的长度成员${parameter[offset]}

除非使用位置参数,否则子字符串索引是从零开始的,在这种情况下,索引默认从 1 开始。 如果offset为 0,并且使用了位置参数,则以$0列表为前缀

所以如果你使用:

"${@:0}"

这也将包括 $0

但是如前所述:

"$@"

将从位置一开始。

PS:请注意,在以前的bash版本中,行为是不同的,"${@:0}"不会包含$0.

  • @anubhava Indeed, thanks. Your answer would be more complete if you quoted that bit too 🙂 That part even sort-of suggests that `${@:offset:length}` is special syntax completely separate from `$@` itself.
  • It is not undocumented. This section implies the behavior `If length is omitted, expands to the substring of the value of parameter starting at the character specified by offset `. So when `offset` is `0` it will expand to `$0 $1 $2...`

以上是为什么echo"$@"不显示脚本名称但显式迭代会显示?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>