bash는 포인터 사용을 지원합니까? 작성할 때 포인터 사용을 지원합니까? ${var[@]}배열을 반복

간단한 질문입니다. bash 쉘이 쉘 스크립트를 작성할 때 포인터 사용을 지원합니까?

${var[@]}배열을 반복 할 때 확장 표기법에 익숙 $var하지만 이것이 배열 인덱스를 반복하는 포인터를 사용하고 있는지는 확실하지 않습니다. bash는 다른 언어와 같은 메모리 주소에 대한 액세스를 제공합니까?

bash가 포인터 사용을 지원하지 않으면 다른 쉘은 무엇을합니까?



답변

포인터 ( 메모리 위치 )는 실제로 파이썬이나 셸과 같은 C보다 높은 수준에서 유용한 개념이 아닙니다. 객체에 대한 참조는 물론 복잡한 데이터 구조를 구축하는 데 필요한 고급 언어에서도 유용합니다. 그러나 대부분의 경우 메모리 주소 측면에서 생각하는 것이 너무 낮아서 매우 유용하지 않습니다.

Bash (및 기타 셸)에서는 ${array[index]}표기법 으로 배열 요소의 값을 가져 와서 할당하고를 사용 array[index]=...하여 배열의 요소 수를 얻을 수 ${#array[@]}있습니다. 괄호 안의 표현식은 산술 표현식입니다. 구성된 예제로서 모든 배열 멤버에 상수 접두사를 추가 할 수 있습니다.

for ((i=0 ; i < ${#array[@]} ; i++ )) ; do
    array[i]="foo-${array[i]}"
done

(만약 우리가 인덱스가 아닌 값에만 관심 for x in "${array[@]}" ; do...이 있다면 괜찮을 것입니다.)

으로 연관 또는 스파 스 배열 , 숫자 루프는 훨씬 이해가되지 않지만, 대신에 우리는 함께 배열의 키 / 인덱스를 가져올 필요 했어 ${!array[@]}. 예 :

declare -A assoc=([foo]="123" [bar]="456")
for i in "${!assoc[@]}" ; do
    echo "${assoc[$i]}"
done 

또한 Bash에는 다른 변수를 간접적으로 가리키는 두 가지 방법이 있습니다.

  • 간접 팽창 사용 구문 변수의 값을 사용하여 이름 인을 한${!var}var
  • namerefsdeclare내장 (또는 ksh호환되는 동의어 typeset) 으로 작성해야합니다 . 변수에 대한 참조를 declare -n ref=var만듭니다 .refvar

Namerefs도 지원 색인, 우리가있는 경우 점에서 arr=(a b c); declare -n ref=arr;다음 ${ref[1]}에 확장됩니다 b. 사용 ${!p[1]}대신 걸릴 p배열로서, 그 두 번째 요소로 명명 된 변수를 참조.

Bash에서 namerefs는 말 그대로 name로 참조 하고 함수 내에서 nameref를 사용하면 명명 된 변수의 로컬 값을 사용합니다. 인쇄 local value of var됩니다.

#!/bin/bash
fun() {
        local var="local value of var"
        echo "$ref";
}
var="global var"
declare -n ref=var
fun

BashFAQ에는 indirection에 대한 기사도 더 있습니다.


답변

아니요, bash“포인터”는 없지만 참조가 있습니다.

$ spam="fred"
$ declare -n tripe=spam
$ echo $tripe
fred
$ tripe=juki
$ echo $spam
juki

로부터 bash매뉴얼 페이지

nameref 또는 다른 변수에 대한 참조를 작성 하기 위해 declare또는 local내장 명령에 -n 옵션을 사용하여 nameref 속성을 변수에 지정할 수 있습니다 . 이를 통해 변수를 간접적으로 조작 할 수 있습니다. nameref 변수가 참조, 지정, 설정 해제 또는 속성이 수정 될 때 (nameref 속성 자체를 사용하거나 변경하는 경우 제외) 실제로 nameref 변수의 값으로 지정된 변수에 대해 작업이 수행됩니다. nameref는 일반적으로 쉘 함수 내에서 이름이 함수의 인수로 전달되는 변수를 참조하기 위해 사용됩니다. 예를 들어 변수 이름이 첫 번째 인수로 쉘 함수에 전달되면

declare -n ref=$1

함수 내에서 nameref 변수 ref가 생성되며 그 값은 첫 번째 인수로 전달 된 변수 이름입니다. 참조에 대한 참조 및 지정 및 속성의 변경은 이름이 $ 1로 전달 된 변수에 대한 참조, 지정 및 속성 수정으로 처리됩니다. for 루프의 제어 변수에 nameref 속성이있는 경우 단어 목록은 쉘 변수 목록이 될 수 있으며 루프가 실행될 때 목록의 각 단어에 대해 이름 참조가 설정됩니다. 배열 변수에는 nameref 속성을 부여 할 수 없습니다. 그러나 nameref 변수는 배열 변수 및 아래 첨자 배열 변수를 참조 할 수 있습니다. unset내장에 -n 옵션을 사용하여 이름 참조를 설정 해제 할 수 있습니다 . 그렇지 않으면unset nameref 변수의 이름을 인수로 사용하여 실행되면 nameref 변수가 참조하는 변수가 설정 해제됩니다.


답변

아니오, 쉘은 “포인터”를 사용하지 않습니다 (C에서 이해되는 것처럼).

배열은 인덱스를 사용할 수 echo "${array[2]}"있지만 @예제에서는 실제로 “포인터”가 아닙니다. “배열 값 목록”을 표현하는 방법입니다. 쉘 파서가 이해하는 것. 방법과 비슷합니다.

$ echo "$@"

모든 “Postional Parameters”목록으로 확장됩니다.


답변

bash 정수 인덱스 배열은 반복적으로 정의되고 액세스 될 수 있지만;

declare -a obj
obj+=("val1")
obj+=("val2")

for item in ${obj[@]}; do
  echo "${obj[${item}]} ${item}"
done

bash의 연관 또는 문자열 기반 인덱스 배열에는 다음과 같은 반복 정의가 필요합니다.

declare -A obj
obj["key1"]="val1"
obj["key2"]="val2"

for item in ${!obj[@]}; do
  echo "${obj[${item}]} ${item}"
done

포인터에 관한 질문과 bash에서 사용하는 질문에 대답하십시오. 컴파일 된 bash 바이너리의 내부 기능은 실제로 스택에 할당 된 메모리에 대한 포인터를 사용하고를 사용하여 유사한 기능을 노출합니다 eval. [간접 참조] http://tldp.org/LDP/abs/html/ivr.html 참조 )

용이있다. 의 사용 eval으로 인해 보안 관련 사항에주의하여 사용해야합니다


답변