Unix$RANDOM函数在Bash终端中不随机
我试图通过在bash终端中使用$random函数在指定范围内生成一个随机数。问题是它生成的数字看起来根本不是随机的。我使用的脚本是:Unix$RANDOM函数在Bash终端中不随机,bash,unix,terminal,Bash,Unix,Terminal,我试图通过在bash终端中使用$random函数在指定范围内生成一个随机数。问题是它生成的数字看起来根本不是随机的。我使用的脚本是: RANDOM=$$; a=$RANDOM b=9; #Number of scripts in collection -1 c=`expr $a % $b `; #Random number between 0 and b if (( c==0 )); then echo "script 1 (random = $a, mod = $c)"; elif (
RANDOM=$$;
a=$RANDOM
b=9; #Number of scripts in collection -1
c=`expr $a % $b `; #Random number between 0 and b
if (( c==0 ));
then
echo "script 1 (random = $a, mod = $c)";
elif (( c==1 ));
then
echo "stript 2 (random = $a, mod = $c)";
...
else
echo "error (random = $a, mod = $c)";
fi;
如果我在for-in循环中运行它,我会得到,例如:
script 8 (random = 17845, mod = 7)
script 8 (random = 18754, mod = 7)
script 8 (random = 19663, mod = 7)
script 7 (random = 20571, mod = 6)
script 7 (random = 21480, mod = 6)
script 6 (random = 22388, mod = 5)
script 6 (random = 23297, mod = 5)
script 6 (random = 24206, mod = 5)
script 5 (random = 25114, mod = 4)
script 5 (random = 26023, mod = 4)
这显然不是随机的
我试着去掉$a,然后就开始跑步了
c=`expr $RANDOM % $b`;
然后将代码更改为另一个变体
c=`expr $a \* $b \/ 32767`;
但这些(毫不奇怪)都返回了相同的结果。我做错了什么?或者这只是对$RANDOM的一个稍微令人恼火的限制?任何建议都将不胜感激。您一直使用相同的数字随机播种。请尝试不要为其设置种子,或使用更随机的项目为其设置种子:
RANDOM=$$
显然,$
并不总是改变,因为它始终是shell的主PID(而不是子shell PID)。如果您实际调用的是不同的shell,那么可能没有太大区别,因为每个PID所播种的数字只增加1。所以你要么删除它,要么在某个地方得到另一个随机种子,比如/dev/uradom
,等等
通过/dev/uradom
应用随机种子的一种好方法:
RANDOM=$(tr -dc 0-9 < /dev/urandom | head -c10)
另外,为了使其在不同的子流程中看起来更独特,请将BASHPID(优于$$)添加到种子:
RANDOM=$(( BASHPID + $(date '+%N') ))
你一直用相同的数字随机播种。请尝试不要为其设置种子,或使用更随机的项目为其设置种子:
RANDOM=$$
显然,$
并不总是改变,因为它始终是shell的主PID(而不是子shell PID)。如果您实际调用的是不同的shell,那么可能没有太大区别,因为每个PID所播种的数字只增加1。所以你要么删除它,要么在某个地方得到另一个随机种子,比如/dev/uradom
,等等
通过/dev/uradom
应用随机种子的一种好方法:
RANDOM=$(tr -dc 0-9 < /dev/urandom | head -c10)
另外,为了使其在不同的子流程中看起来更独特,请将BASHPID(优于$$)添加到种子:
RANDOM=$(( BASHPID + $(date '+%N') ))
我认为可以找到这样的解释: 当您使用模运算时,您正在从中选择信息 一个数字的低阶位,并从中丢弃信息 高阶位。。。X的最低有效位(右侧)为 不是很随机,所以基于数字X的决策应该总是 主要受最重要数字的影响 使用它对我来说效果更好(尽管我只测试了几次): 以下是修改后的脚本:
#!/bin/bash
RANDOM=$$;
a=$RANDOM
b=9; #Number of scripts in collection -1
c=$(($a * $b / 32768))
if (( c==0 )); then
echo "script 1 (random = $a, mod = $c)";
elif (( c==1 )); then
echo "script 2 (random = $a, mod = $c)";
else
echo "error (random = $a, mod = $c)";
fi;
希望这能有所帮助。我认为可以找到以下解释: 当您使用模运算时,您正在从中选择信息 一个数字的低阶位,并从中丢弃信息 高阶位。。。X的最低有效位(右侧)为 不是很随机,所以基于数字X的决策应该总是 主要受最重要数字的影响 使用它对我来说效果更好(尽管我只测试了几次): 以下是修改后的脚本:
#!/bin/bash
RANDOM=$$;
a=$RANDOM
b=9; #Number of scripts in collection -1
c=$(($a * $b / 32768))
if (( c==0 )); then
echo "script 1 (random = $a, mod = $c)";
elif (( c==1 )); then
echo "script 2 (random = $a, mod = $c)";
else
echo "error (random = $a, mod = $c)";
fi;
希望这有帮助。同时使用
(())
比expr
更清晰。像((c=RANDOM%b))
或((c=a*b/3276))
这样就解决了我的问题!似乎是我的mod序列导致了这个问题。仍然不确定为什么((c=RANDOM%b))会比c=expr$RANDOM%$b
更随机;不过还是要谢谢你。啊,我看到它是随机的,而不是$RANDOM,因此每次播种一个不同的数字。另外,使用(())
比使用expr
更清晰。像((c=RANDOM%b))
或((c=a*b/3276))
这样就解决了我的问题!似乎是我的mod序列导致了这个问题。仍然不确定为什么((c=RANDOM%b))会比c=expr$RANDOM%$b
更随机;不过还是要谢谢你。啊,我看到它是随机的,而不是$RANDOM,因此每次播种一个不同的数字。感谢$$上的信息-我刚刚尝试了RANDOM=$(tr-dc 0-9?它似乎也不喜欢这样-至少我得到了相同的随机变量。将mod序列更改为((c=RANDOM%b))似乎实际上解决了这个问题。谢谢你的帮助!$$是“getpid”的另一种方式,如果您正在重新启动脚本,您将期望它增加一个(或者如果在此期间启动了另一个进程,则增加两个),感谢$$上的信息-我刚刚尝试了RANDOM=$(tr-dc 0-9?它似乎也不喜欢这样-至少我得到了相同的随机变量。将mod序列更改为((c=RANDOM%b))似乎实际上解决了这个问题。谢谢你的帮助!$$是“getpid”的另一种方式,如果您正在重新启动脚本,您将期望它增加一个(或者如果在此期间启动了备用进程,则增加两个)。我确实看到了这一点,但它似乎没有太大变化(但我将使用/32767版本)-解决方案似乎使用((c=RANDOM%b))或((c=a*b/32767)),这两种方法都会导致一个足够随机的数字。我确实看到了这一点,但它似乎没有太大变化(但我将使用/32767版本)-解决方案似乎使用了((c=random%b))或((c=a*b/32767)),这两种方法都会导致一个足够随机的数字。