Considere o exemplo a seguir, parece que está funcionando bem com o índice 0
:
$ a1=(1 2 3)
$ a2=(a b c)
$ for x in a1 a2; do echo "${!x}"; done
1
a
$ for x in a1 a2; do echo "${!x[0]}"; done
1
a
No entanto, com o índice 1
, ele não imprime nada:
$ for x in a1 a2; do echo "${!x[1]}"; done
Arrays por si só são bons:
$ echo "${a1[1]} ${a2[1]}"
2 b
Editar - Um caso de uso da vida real baseado na resposta do ilkkachu
SHIBB=(https://shibboleth.net/downloads/service-provider/3.0.2/ shibboleth-sp-3.0.2 .tar.gz)
XERCES=(http://apache.mirrors.nublue.co.uk//xerces/c/3/sources/ xerces-c-3.2.1 .tar.gz)
XMLSEC=(http://apache.mirror.anlx.net/santuario/c-library/ xml-security-c-2.0.1 .tar.gz)
XMLTOOL=(http://shibboleth.net/downloads/c++-opensaml/latest/ xmltooling-3.0.2 .tar.gz)
OPENSAML=(http://shibboleth.net/downloads/c++-opensaml/latest/ opensaml-3.0.0 .tar.gz)
typeset -n x
for x in XERCES XMLSEC XMLTOOL OPENSAML SHIBB; do
url="${x[0]}" app="${x[1]}" ext="${x[2]}"
[ -f "./${app}${ext}" ] || wget "${url}${app}${ext}"
tar -xf "./${app}${ext}"
cd "./${app}" && ./configure && make -j2 && make install && ldconfig
cd ..
done
"${!x[1]}"
é uma referência indireta usando o elemento no índice1
do arrayx
.Nas versões atuais do Bash (4.3 e acima), você pode usar namerefs para obter o que deseja:
ou seja, com o nameref configurado,
"${y[3]}"
é uma referência ao elemento3
no array nomeado pory
.Para fazer um loop sobre os arrays como você faz na sua pergunta, você simplesmente faria
x
um nameref.As atribuições feitas pelo
for
loop alteram o valor dex
si mesmo (alterando para o que a referência aponta). Uma atribuição regular (x=123
, oux[1]=123
) altera a variável atualmente referenciada porx
. Portanto, isso mudaria ambosa1[1]
ea2[1]
parafoo
:A razão
"${!x[0]}"
parece funcionar é quex
ex[0]
são equivalentes. Se você tivesseecho "${x[0]}"
dentro do seu loop (sem o estrondo), você obteriaa1
,a2
, o mesmo que comecho "$x"
.