![간접적으로 참조되는 변수가 설정되지 않았는지 확인하는 방법](https://linux55.com/image/111200/%EA%B0%84%EC%A0%91%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EC%B0%B8%EC%A1%B0%EB%90%98%EB%8A%94%20%EB%B3%80%EC%88%98%EA%B0%80%20%EC%84%A4%EC%A0%95%EB%90%98%EC%A7%80%20%EC%95%8A%EC%95%98%EB%8A%94%EC%A7%80%20%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
function setProperty () {
local name="${1}"
local Id=${2}
local _thisVarNam=_${name}_${3}
for (( ctX=0 ; ctX<${2} ; ctX++ )) ; do
if [[ -z ${!_thisVarNam[${ctX}]+x} ]] ;then
echo "${ctX} is unset"
eval "$_thisVarNam[${ctX}]=" #so set it
else
echo "set"
fi
done
echo
}
for (( ctY=0 ; ctY<4 ; ctY++ )) ; do
setProperty "First" ${ctY} "Second"
done
이 코드는 다음을 출력합니다.
0 is unset
set
1 is unset
set
1 is unset
2 is unset
따라서 ${_First_Second[${ctX}]}가 아니라 ${_First_Second[0]}가 설정 해제되었는지 매번 확인합니다. 조건을 직접 참조로 변경하면
if [[ -z ${_First_Second[${ctX}]+x} ]] ;then
그것은 출력한다
0 is unset
set
1 is unset
set
set
2 is unset
이것이 내가 기대하는 것입니다. 내가 뭘 잘못했나요?
if [[ -z ${!_thisVarNam[${ctX}]+x} ]] ;then
Bash 버전 3.2.57(1) 사용
답변1
글쎄요, 제 생각에는 모든 변수를 표시하지 않은 것 같지만( _First_Second
설정된 위치는 언급하지 않았습니다) 제 생각에는 다음과 같습니다.
${!_thisVarNam[${ctX}]+x}
값을 읽어 _thisVarNam[${ctX}]
변수 이름으로 사용합니다. 이는 값을 가져와 _thisVarNam
이를 배열 이름으로 사용한 다음 인덱싱하는 것과 다릅니다 .저것대량으로.
보자:
$ P=(somevar othervar);
$ somevar=foo; unset othervar
$ i=0; echo "${!P[i]-unset}" # reads somevar
foo
$ i=1; echo "${!P[i]-unset}" # reads othervar (not set)
unset
$ q="P[0]"; echo "${!q}" # reads P[0]
somevar
$ q="P[1]"; echo "${!q}" # reads P[1]
othervar
$ arrayname=P; i=1
$ q="$arrayname[$i]" # this is just a string so same as above
$ echo "${!q}" # still P[1]
othervar
따라서 _thisVarNam
배열 이름을 포함하고 해당 배열의 구성원이 설정 해제되었는지 확인하려면 다음을 수행해야 합니다.
p="$_thisVarNam[${ctX}]"
if [ -z "${!p+x}" ] ; then ...
그건 그렇고, Bash에서는 declare
정확히 다음을 사용하지 않고 간접 참조를 사용하여 간접적으로 변수를 설정할 수 있습니다 eval
.
$ arrayname=P; i=19
$ declare "$arrayname[$i]"=qwerty
$ echo "${P[19]}"
qwerty