間接的に参照される変数が設定されていないことを確認する方法

間接的に参照される変数が設定されていないことを確認する方法
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

おすすめ記事