是否可以将 bash 数组作为参数传递给函数?

是否可以将 bash 数组作为参数传递给函数?

我想将数组传递给 bash 函数,但出现bad substitution错误

例子


mapfile -t ray < <(parallel -j 0 echo ::: {1..10})

declare -p ray

declare -a ray=([0]="2" [1]="1" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9" [9]="10")

arrLen() {
  echo "${#$1[@]}"
 }

arrLen ray

-bash: ${#$1[@]}: bad substitution

那么是否不可能将参数传递给 bash 数组呢?

答案1

对于最新版本的 bash,您可以使用 namerefs:

arrLen() {
  typeset -n __Var="$1"
  echo "${#__Var[@]}"
}

在这里,我们选择__Var作为 nameref 变量名称,因为它不太可能在脚本中以其他方式使用。arrLen __Var因错误而失败circular name reference

Namerefs(就像typeset一般的 、 和 bash 的数组设计)是 bash 从 Korn shell 借用的一个功能。在 ksh(引入 namerefs 的 ksh93)中,您可以编写:

function arrLen {
  typeset -n var="$1"
  echo "${#var[@]}"
}

(ksh namerefs 能够从调用者的作用域(或全局作用域)引用具有相同名称的变量,但作用域(静态作用域)仅在使用 Korn 语法声明的函数中完成,而不是在使用 Bourne 语法声明的函数中完成)

或者您始终可以使用eval动态构造代码。

arrLen() {
  eval 'echo "${#'"$1"'[@]}"'
}

zsh

arrLen() echo ${(P)#1}

bash Nameref 解析,zsh 的P参数扩展标志也在eval后台执行某种形式的(动态代码评估),因此如果传递给的参数arrLen不能保证是有效的变量名,则所有这些方法都同样不安全,但如果它们是有效的变量名,则同样安全。

相关内容