Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix$RANDOM函数在Bash终端中不随机_Bash_Unix_Terminal - Fatal编程技术网

Unix$RANDOM函数在Bash终端中不随机

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 (

我试图通过在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 (( 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)),这两种方法都会导致一个足够随机的数字。