在Bash Shell脚本中生成1到10之间的随机数

A15*_*A15 173 bash

如何在Bash Shell脚本中生成1到10之间的包含性随机数?

会的$(RANDOM 1+10)吗?

Ora*_*Tux 285

$(( ( RANDOM % 10 )  + 1 ))
Run Code Online (Sandbox Code Playgroud)

编辑.根据评论将括号更改为括号. http://web.archive.org/web/20150206070451/http://islandlinux.org/howto/generate-random-numbers-bash-scripting

  • `%10`将结果减少到0-9的范围.但是,最顶层的范围只有0-7.因此,8和9的抽奖比0-7少两个.+ 1将其转换为对9和10的偏差.这将是安全背景中的一个主要缺陷 - RNG不得显示偏差,并且在规模上这是显而易见的.进一步的解释:[伪随机数生成器的剖析 - 可视化Cryptocat的有缺陷的PRNG](http://nakedsecurity.sophos.com/2013/07/09/anatomy-of-a-pseudorandom-number-generator-visualising-cryptocats-buggy -prng /). (36认同)
  • @ ads20000文档说,`man bash`,"每次引用此参数时,都会生成0到32767之间的随机整数." 请注意,这不是bash错误,这是实现者的错误.假设bash正确地实现了`$ RANDOM`,那么从0到32767应该有一个公平的抽奖,但是因为你不能将它平均分成10个组,所以在这个实现中对9和10的偏差非常小.大多数人不应该担心这一点,因为无论如何你都不应该使用`$ RANDOM`作为安全目的. (4认同)
  • @MichaelChirico您可以通过Archive.org访问完整的解释(现已死亡):http://web.archive.org/web/20150206070451/http://islandlinux.org/howto/generate-random-numbers-bash-脚本 - 我现在编辑了上面的答案以反映这一点 (2认同)

Rei*_*ase 75

最简单的解决方案是使用允许您直接指定范围的工具,例如 shuf

shuf -i1-10 -n1
Run Code Online (Sandbox Code Playgroud)

如果你想使用$RANDOM,那么将0 ... 32767中的最后8个数字丢掉会更精确,只需将其视为0 ... 32759,因为从0 ... 32767 mod 10获得以下分布

0-8 each: 3277 
8-9 each: 3276
Run Code Online (Sandbox Code Playgroud)

所以,稍慢但更精确

while :; do ran=$RANDOM; ((ran < 32760)) && echo $(((ran%10)+1)) && break; done 
Run Code Online (Sandbox Code Playgroud)


Abh*_*ogi 32

要使用bash生成随机数,请使用$ RANDOM内部Bash函数.请注意,$ RANDOM不应用于生成加密密钥.$ RANDOM是使用您当前的进程ID(PID)和当前时间/日期生成的,该时间/日期由自1970年以来经过的秒数定义.

 echo $RANDOM % 10 + 1 | bc
Run Code Online (Sandbox Code Playgroud)

  • “| bc”部分有什么作用? (2认同)
  • @ebi `echo` 只是打印字符串(变量替换发生在命令被处理之前,所以 `$RANDOM` 已经被替换为一个整数),`bc` 是当 `|` 重定向从`echo` 到`bc` 的stdin 的stdout (2认同)

cho*_*oba 23

您也可以使用/ dev/urandom:

grep -m1 -ao '[0-9]' /dev/urandom | sed s/0/10/ | head -n1
Run Code Online (Sandbox Code Playgroud)

  • 没有$ RANDOM可用时很有用,即busybox (4认同)

Tho*_*att 17

要生成范围:{0,..,9}

r=$(( $RANDOM % 10 )); echo $r

要生成范围:{40,..,49}

r=$(( $RANDOM % 10 + 40 )); echo $r