"${!x[1]}" é uma referência indireta usando o elemento no índice 1 da matriz x .
$ foo=123; bar=456; x=(foo bar); echo "${!x[1]}"
456
Nas versões atuais do Bash (4.3 e acima), você pode usar namerefs para obter o que deseja:
$ a=(00 11 22 33 44)
$ typeset -n y=a
$ echo "${y[3]}"
33
ou seja, com o nameref configurado, "${y[3]}" é uma referência ao elemento 3 na matriz denominada por y .
Para repetir os arrays como você faz na sua pergunta, basta criar x a nameref.
a1=(1 2 3); a2=(a b c)
typeset -n x;
for x in a1 a2; do
echo "${x[1]}"
done
As atribuições feitas pelo loop for alteram o valor de x em si (mudando para o que a referência aponta). Uma atribuição regular ( x=123 ou x[1]=123 ) altera a variável atualmente referenciada por x . Então, isso mudaria os dois a1[1] e a2[1] para foo :
typeset -n x;
for x in a1 a2; do
x[1]=foo
done
O motivo "${!x[0]}" parece funcionar é que x e x[0] são equivalentes. Se você tivesse echo "${x[0]}" dentro de seu loop (sem o estrondo), você obteria a1 , a2 , o mesmo que com echo "$x" .