As other answers have stated, Zsh $RANDOM
doesn't behave the same as bash and repeats the same sequence if invoked within a subshell. That behavior can be seen with this simple example:
$ # bash: different numbers; zsh: all the same number
$ for i in {0..99}; do echo $(echo $RANDOM); done
22865
22865
...
22865
What the other answers don't cover is how do get around this behavior in Zsh. While echo $RANDOM >/dev/null
helps if you know $RANDOM
was invoked, it doesn't help much if it's tucked away in a function you're writing. That puts extra burden on the caller to do this weird echo:
function rolldice {
local i times=${1:-1} sides=${2:-6}
for i in $(seq $times); do
echo $(( 1 + $RANDOM % $sides ))
done
}
# all 4 players rolled the exact same thing!
for i in {1..4}; do echo $(rolldice 10); done
# seriously 🙄...
for i in {1..4}; do echo $(rolldice 10); echo $RANDOM >/dev/null; done
While it's more expensive (slower) to do, you could get around this by running $RANDOM
within a new Zsh session to get results similar to Bash:
function rolldice {
local i times=${1:-1} sides=${2:-6}
for i in $(seq $times); do
echo $(( 1 + $(zsh -c 'echo $RANDOM') % $sides ))
done
}
# now all 4 players rolled different results!
for i in {1..4}; do echo $(rolldice 10); done
There are other better ways than using $RANDOM
to get a uniformly random number in Zsh, but this works in a pinch. One popular alternative is random=$(od -vAn -N4 -t u4 < /dev/urandom); echo $random
.