如何检查间接引用的变量是否未设置

如何检查间接引用的变量是否未设置
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[0]} 每次是否未设置,而不是 ${_First_Second[${ctX}]}。如果我将条件更改为直接引用

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

相关内容