Você pode fazer o que quiser copiando a matriz em uma variável local e, em seguida, selecionando a partir dessa matriz:
rand_var() {
local nm="$1[@]"
local tmp=("${!nm}")
printf "%s\n" "${tmp[RANDOM % ${#tmp[@]}]}"
}
Eu não acho que você pode fazer isso de outra forma, porque você não pode indireto para o comprimento da matriz. Se você passou no tamanho da função também:
rand_var_len() {
local nm="$1[$((RANDOM % $2))]"
printf "%s\n" "${!nm}"
}
rand_var_len array ${#array[@]}
você pode fazer isso sem copiar.
Para evitar ambos, você precisará usar um dos eval
-alikes.