bash 对特殊变量有不同的弱引用规则吗?

mag*_*nus 6 bash shell-script quoting

我不认为我完全理解在 bash 中引用的细微差别。

我有一个脚本,foo.sh,它只是输出编号的参数。

#!/bin/bash

i=1
while [ $i -le $# ] ; do
    v=$(eval "echo \$$i")
    echo "$i: $v"
    i=$((i + 1))
done
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

me@localhost] ./foo.sh a b c
1: a
2: b
3: c
Run Code Online (Sandbox Code Playgroud)

如果我将变量设置为args包含空格的值(如"super nintendo"),我可以使用无引号让 bash 将其视为两个参数:

me@localhost] args="super nintendo" ; ./foo.sh $args
1: super
2: nintendo
Run Code Online (Sandbox Code Playgroud)

或者我可以使用弱引用(双引号)让 bash 将其视为单个参数,但将变量扩展为实际值:

me@localhost] args="super nintendo" ; ./foo.sh "$args"
1: super nintendo
Run Code Online (Sandbox Code Playgroud)

或者我可以使用强引用(单引号)将其字面视为输入:

me@localhost] args="super nintendo" ; ./foo.sh '$args'
1: $args
Run Code Online (Sandbox Code Playgroud)

但是,弱引用特殊变量$@似乎就像没有引用一样。例如,bar.sh下面调用foo.sh两次,一次使用弱引用,一次不使用引用。

#!/bin/bash

./foo.sh "$@"
./foo.sh $@
Run Code Online (Sandbox Code Playgroud)

调用此 with./bar.sh a b c为两个调用生成相同的输出foo.sh

1: a
2: b
3: c
1: a
2: b
3: c
Run Code Online (Sandbox Code Playgroud)

希望看到的是以下内容:

1: a b c
1: a
2: b
3: c
Run Code Online (Sandbox Code Playgroud)

在这里用 bash 引用我错过了什么?

cho*_*oba 13

那是因为$@是一个数组,而数组的引用有不同的规则:

  • "${array[@]}""$@"扩展为数组成员
  • "${array[*]}""$*"扩展为由$IFS变量中的第一个字符连接的数组元素。

尝试使用几个参数,其中一些包含空格:

./foo.sh 'one two' three
Run Code Online (Sandbox Code Playgroud)