Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
939 views
in Technique[技术] by (71.8m points)

shell - References to $RANDOM in subshells all returning identical values

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...