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では、namerefを使用できます。

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

ここでは__Var、スクリプトで他の方法で使用される可能性が低いため、変数名をnamerefとして選択します。arrLen __Varエラーのため失敗しましたcircular name reference

Namerefs(typeset通常とbashの配列デザインなど)は、bashがKornシェルから借りた機能です。 ksh(namerefsを導入したksh93)では、次のように作成できます。

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

(ksh namerefは呼び出し元の範囲(またはグローバル範囲)で同じ名前の変数を参照できますが、範囲指定(静的範囲指定)はBourne構文ではなくKorn構文を使用して宣言された関数でのみ実行されます。される)

または、いつでもeval動的に生成されたコードを使用できます。

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

そしてzsh

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

bash Namerefの解析、zshのパラメータP拡張フラグはeval背後で任意の形式(動的コード評価)を実行するため、渡されたパラメータが有効arrLenな変数名であることは保証されませんが、有効な変数名である場合、これらのメソッドはすべて安全ではありません。変数名も同様に安全です。

おすすめ記事