Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

References to $RANDOM in subshells all returning identical values

Tags:

shell

random

zsh

The following short script prints a random ten-digit binary number:

#!/usr/bin/zsh
point=''
for i in `seq 1 10`
do
    echo $RANDOM >/dev/null
    point=$point`if [ $RANDOM -gt 16383 ]; then echo 0; else echo 1; fi`
done
echo $point

However, if I remove the apparently useless echo $RANDOM >/dev/null line, the script always prints either 1111111111 or 0000000000.

Why?

like image 755
Daniel Wagner Avatar asked Sep 15 '15 03:09

Daniel Wagner


1 Answers

Subshells (as created by backticks, or their modern replacement $()) execute in a different context from the parent shell -- meaning that when they exit, all process-local state changes -- including the random number generator's state -- are thrown away.

Reading from $RANDOM inside the parent shell updates the RNG's state, which is why the echo $RANDOM >/dev/null has an effect.

That said, don't do that. Do something like this, which has no subshells at all:

point=
for ((i=0; i<10; i++)); do
  point+=$(( (RANDOM > 16383) ? 0 : 1 ))
done

If you test this generating more than 10 digits -- try, say, 1000, or 10000 -- you'll also find that it performs far better than the original did.

like image 189
Charles Duffy Avatar answered Nov 02 '22 19:11

Charles Duffy