Como verificar se uma variável referenciada indiretamente está indefinida

0
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

Este código gera

0 is unset

set
1 is unset

set
1 is unset
2 is unset

Portanto, é apenas verificar se $ {_ First_Second [0]} está indefinido a cada vez, não $ {_ First_Second [$ {ctX}]}. Se eu alterar o condicional para referência direta

if [[ -z ${_First_Second[${ctX}]+x} ]] ;then

gera

0 is unset

set
1 is unset

set
set
2 is unset

que é o que estou esperando. O que estou fazendo de errado com

if [[ -z ${!_thisVarNam[${ctX}]+x} ]] ;then

Usando a versão bash 3.2.57 (1)

    
por user1321964 10.05.2017 / 10:04

1 resposta

2

Bem, você não acha que mostrou todas as suas variáveis (não há referência para onde _First_Second está definido), mas acho que:

${!_thisVarNam[${ctX}]+x}

lê o valor de _thisVarNam[${ctX}] e usa isso como um nome de variável. O que não é o mesmo que pegar o valor de _thisVarNam , usar isso como um nome de matriz e, em seguida, indexar essa matriz.

Vamos ver:

$ 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

Portanto, se _thisVarNam contiver o nome de uma matriz e você quiser verificar se um membro dessa matriz não está definido, será necessário fazer algo assim:

p="$_thisVarNam[${ctX}]"
if [ -z "${!p+x}" ] ; then ...

Como um aparte, no Bash, você pode usar declare para definir uma variável indiretamente, não há necessidade da força total de eval :

$ arrayname=P; i=19
$ declare "$arrayname[$i]"=qwerty
$ echo "${P[19]}"
qwerty
    
por 10.05.2017 / 10:24