${parameter:?word} 数组范围扩展

${parameter:?word} 数组范围扩展

${parameter:?word}如果变量未设置,则打印给定的错误消息:

$ echo ${unset_var?badness}
bash: unset_var: badness

如何在数组上使用它?

$ array=(a b c)
$ echo "${array[@]:1:2}"
b c

和:

$ echo "${array[@]:1:2?Need at least two arguments}"

bash抱怨:

bash: array[@]: a: expression recursion level exceeded (error token is "a")

zsh抱怨:

zsh: bad math expression: operator expected at `a least tw...'

这对于位置参数的“工作方式”也不同:

$ echo ${1?Argument not given}
bash: 1: Argument not given

我们可以打印数组中的范围,例如:

$ set a b c
$ echo ${@:2}
b c

或者,另一种选择:

$ echo ${@:2:$#-1}
b c

bash:

$ set a b c
$ echo ${@:2?badness}
bash: @: 2?badness: `:' expected for conditional expression (error token is "badness")
$ echo ${@:2:$#-1?badness}
bash: @: 3-1?badness: `:' expected for conditional expression (error token is "badness")

zsh:

% set a b c
% echo ${@:2?badness}
zsh: bad math expression: ':' expected
% echo ${@:2:$#-1?badness}
zsh: bad math expression: ':' expected

有没有一种方法对两者都有效{z,ba}sh

答案1

在 zsh 中,你可以这样做:

printf ' - "%s"\n' "${(@)a[1,4]}" "${a[5]?Need at least 5 elements}"

在 bash 中也是如此,但仅适用于非稀疏数组,就像${a[@]:0:5}在 ksh 中一样,其数组设计 bash 已大部分复制,这会为您提供索引 >= 0 的前 5 个元素,因此其中可能有超过 5 个元素索引为 4 的索引未设置(请记住,数组索引从 0 开始,而不是 bash 中的 1),或者索引 4 的索引设置为唯一一组。

a=( "${a[@]}" ) # unsparsify the array
printf ' - "%s"\n' "${a[@]:0:4}" "${a[4]?Need at least 5 elements}"

或者你可以做明智的事情并写下:

(( $#a >= 5 )) || die 'Need at least 5 elements.' # zsh
(( ${#a[@]} >= 5 )) || die 'Need at least 5 elements.' # ksh/bash (or zsh)

而不是试图太过花哨。

相关内容