간단한 질문입니다. 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
- namerefs 는
declare
내장 (또는ksh
호환되는 동의어typeset
) 으로 작성해야합니다 . 변수에 대한 참조를declare -n ref=var
만듭니다 .ref
var
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
으로 인해 보안 관련 사항에주의하여 사용해야합니다