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유효한 변수 이름이라고 보장되지 않지만 유효한 변수 이름인 경우 이러한 모든 방법은 동일하게 안전하지 않습니다. 변수 이름도 똑같이 안전합니다.

관련 정보