如何输出“$@”的单个元素?

use*_*935 5 bash parameter

我读过这$@是一个保存位置参数的数组。

我试图输出$@数组的一个元素:

echo ${@[1]}
Run Code Online (Sandbox Code Playgroud)

但是bash给了我这个错误:

test.sh: line 1: ${@[1]}: bad substitution
Run Code Online (Sandbox Code Playgroud)

Jef*_*ler 15

$@是一个“特殊参数”,而不是一个数组;因此,您不能将其作为数组访问。您可以使用它们的位置直接访问参数: ${1}... ${n}

$ set -- a b c d e f g h i j k l m n
$ echo "$#"
14
$ echo "${10}"
j
Run Code Online (Sandbox Code Playgroud)

因为我对参数 10+ 的支撑行为很好奇,所以我对各种 shell 进行了测试:

for shell in ash bash dash fish ksh mksh posh rc sash yash zsh
do
  printf "The %s shell outputs: %s\n" "$shell" "$($shell -c 'set -- a b c d e f g h i j k l m n; echo $10')"
done
Run Code Online (Sandbox Code Playgroud)

有了这些结果:

The ash shell outputs: j
The bash shell outputs: a0
The dash shell outputs: j
The fish shell outputs:
The ksh shell outputs: a0
The mksh shell outputs: a0
The posh shell outputs: a0
rc: cannot find `set'
The rc shell outputs:
The sash shell outputs: j
The yash shell outputs: a0
The zsh shell outputs: j
Run Code Online (Sandbox Code Playgroud)

Shell 参数的花括号行为在Shell 命令语言部分的 Shell 参数扩展中进行了解释:

参数名称或符号可以用大括号括起来,大括号是可选的,除了位置参数超过一位...

$@特殊参数本身是在同一页上描述的特殊参数部分。

  • 那么对于 1 到 9,你真的不需要括号......我相信这是众所周知的,但我认为最好在答案中提及这一点。 (5认同)
  • 你不需要括号 0..9,真的,但你需要 10+,并且在 0..9 使用它们时不会受到伤害。 (3认同)
  • 你可以在 `$@` 上做一个数组切片,比如 `echo "${@:1:1}"` 来获取第一个参数。不确定当您可以使用“$1”时是否有这样做的情况,但它就在那里。 (2认同)

ImH*_*ere 5

$@是实际上的值的列表,而不是阵列。数组语法实际上不起作用。它们被称为“位置参数”,通常通过$4语法访问(例如)。

在 bash 中:

$ set -- a b c d e f g h i j k l m n
$ echo $6
f
$ echo "${11}"
k
$ echo "${@:11:1}"
k
Run Code Online (Sandbox Code Playgroud)

带索引:

$ i=11
$ echo "${@:i:1}"
k
$ echo "${!i}"
k
Run Code Online (Sandbox Code Playgroud)

在较旧的 shell 上,除了使用 eval(注意风险)别无他法:

$ eval 'var=$'"{$i}"
$ echo "$var"
k
Run Code Online (Sandbox Code Playgroud)

循环

循环易于管理,只需使用 for var; do …; done

$ for pos; do printf '%s:' "$pos"; done; echo
a:b:c:d:e:f:g:h:i:j:k:l:m:n:
Run Code Online (Sandbox Code Playgroud)

shell 会自动使列表中的每个值可用于每个循环。