1

Here is my attempt:

rand_var() {
printf "%s\n" "${${!1}[RANDOM % ${#${!1}[@]}]}"
}

And I run it like this

array=("something" "somethingelse" "test")
rand_var array

However, it tells me bad substitution. I think it may have something to do with the variables and quoting but I can't figure it out, I use ${!1} so that it acctually uses the contents of the variable and not just array. This line has worked before when I specify the variable name instead of ${!1}.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
DisplayName
  • 11,468
  • 20
  • 73
  • 115

1 Answers1

1

You can do what you want by copying the array into a local variable, and then selecting from that array:

rand_var() {
    local nm="$1[@]"
    local tmp=("${!nm}")
    printf "%s\n" "${tmp[RANDOM % ${#tmp[@]}]}"
}

I don't think you can do it otherwise, because you can't indirect to the length of the array. If you passed in the length to the function as well:

rand_var_len() {
    local nm="$1[$((RANDOM % $2))]"
    printf "%s\n" "${!nm}"
}
rand_var_len array ${#array[@]}

then you could do it without any copying.

To avoid both, you'll need to use one of the eval-alikes.

Michael Homer
  • 74,824
  • 17
  • 212
  • 233