Answers:
在ksh
,Bash,Zsh,Yash或BusyBox中sh
:
[ "$RANDOM" -lt 3277 ] && do_stuff
RANDOM
每次对其进行评估时,Korn,Bash,Yash,Z和BusyBox外壳程序的特殊变量都会生成一个介于0到32767之间的伪随机十进制整数值,因此上面给出的机会(接近)为十分之一。
您可以使用它来产生一个函数,该函数的行为至少在Bash中如您所描述的那样:
function chance {
[[ -z $1 || $1 -le 0 ]] && return 1
[[ $RANDOM -lt $((32767 / $1 + 1)) ]]
}
忘记提供参数或提供无效参数将产生1的结果,因此chance && do_stuff
永远不会do_stuff
。
这使用的通用公式“ n中的 1 ” $RANDOM
,即在32768中[[ $RANDOM -lt $((32767 / n + 1)) ]]
获得(⎣32767/ n / + 1)的机会。其值n
不是32768的因数,因为可能值范围内的不均匀分割而引入了偏差。
$((32767/parts+1))
大于1,否则我们会面临零件数量增加1的风险,而相除的结果(因此极限)相同。(续)
(32767/n-32767/(n+1))>=1
,求解n给出约181.5的极限。实际上,零件数量最多可以达到194个。但是在195份时,结果极限为151,与194份时相同。那是不一致的,应该避免。简而言之,零件数量(n)的上限应为194。您可以进行极限测试:[[ -z $1 || $1 -le 1 || $1 -ge 194 ]] && return 1
非标解决方案:
[ $(date +%1N) == 1 ] && do_stuff
检查当前时间的最后一位(以纳秒为单位)是否为1!
[ $(date +%1N) == 1 ] && do_stuff
不会定期进行,否则会破坏随机性。认为while true; do [ $(date +1%N) == 1 ] && sleep 1; done
是一个抽象的反例。但是,玩纳秒级的想法真的很好,我想我会用它,因此+1
clock_getres()
),2)禁止调度程序,例如,始终在100纳秒边界上启动时间片(即使时钟正确,也会引入偏差)。3)(通常)从中读取/dev/urandom
或检查的值是获得随机值的受支持方法$RANDOM
。
使用的替代方法$RANDOM
是shuf
命令:
[[ $(shuf -i 1-10 -n 1) == 1 ]] && do_stuff
会做的工作。对于从文件中随机选择行也很有用,例如 音乐播放列表。
改善第一个答案,并使您要实现的目标更加明显:
[ $(( $RANDOM % 10 )) == 0 ] && echo "You win" || echo "You lose"
$RANDOM % 10
会产生偏差,除非$RANDOM
产生正好是10个不同值的倍数(通常在二进制计算机中不会发生)
"$RANDOM" -lt $((32767 / n + 1))
。