let is only for arithmetic operations. Your strings have no numeric value (unless they name variables which themselves have numeric values), so they all evaluate to 0 in that context.
Make it:
constraint="${constraints[${rand}]}"
...with no let.
In context, this might look like:
constraints=(A B C E Q P S)
rand=$(( RANDOM % ${#constraints[@]} ))
constraint=${constraints[${rand}]}
echo "$constraint"
Note:
- See the bash-hackers' wiki page on obsolete syntax for discussion of
$[ ] and let. Neither is good form in modern scripting.
- Quotes are not needed (though it's safe to use them, and good practice to do so whenever unsure!) on items that parse unambiguously to a single word during an assignment, as both string-splitting and glob expansion are turned off by default in this context.
- Quotes are needed for
echo $var if the values themselves, or the value of the IFS variable, are unknown or not controlled. See BashPitfalls #14.
let.letmakes your operation arithmetic. All the stringsA,B,C,E,Q,PandSevaluate to arithmetic 0.$[ ... ]is 1970s-era math syntax; on modern (post-1991-POSIX-sh) shells, use$(( ))instead of either that orlet.$RANDOMisn't the typical choice if you're deciding a lottery or generating keys to encrypt military secrets, after all), but if${#constraints[@]}doesn't divide evenly into 32768, then the "random" choice being made here isn't quite fairly weighted. If in a case where this matters, you'll want to compare the randomly-chosen value to see if it's greater than$(( 32768 - (32768 % ${#constraints[@]}) ))and pick a different random number until that isn't true.