Bash

是否可以將 bash 數組作為參數傳遞給函式?

  • August 15, 2022

我想將數組傳遞給 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 數組?

對於最新版本的 bash,您可以使用 namerefs:

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

在這裡,我們選擇__Varnameref 變數名稱作為在您的腳本中不太可能使用的變數名稱。因錯誤而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.

引用自:https://unix.stackexchange.com/questions/713662