【发布时间】:2012-02-17 19:36:50
【问题描述】:
如何在 Bash Shell 脚本中生成 1 到 10 之间的包含随机数?
是$(RANDOM 1+10)吗?
【问题讨论】:
-
这可以满足我的需要
export CUDA_VISIBLE_DEVICES=$((( RANDOM % 8 )))
标签: bash
如何在 Bash Shell 脚本中生成 1 到 10 之间的包含随机数?
是$(RANDOM 1+10)吗?
【问题讨论】:
export CUDA_VISIBLE_DEVICES=$((( RANDOM % 8 )))
标签: bash
$(( ( RANDOM % 10 ) + 1 ))
编辑。根据评论将括号更改为括号。 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 不得显示偏见,并且在规模上这是显而易见的。进一步说明:Anatomy of a pseudorandom number generator - visualising Cryptocat's buggy PRNG.
man bash,“每次引用此参数时,都会生成一个介于 0 和 32767 之间的随机整数。”请注意,这不是 bash 错误,而是实施者的错误。假设 bash 正确实现了$RANDOM,从数字 0 到 32767 应该是公平的,但是因为你不能将它平均分成 10 个组,所以在这个实现中对 9 和 10 的偏差很小。大多数人不必担心这一点,因为无论如何您都不应该出于安全目的使用$RANDOM。
最简单的解决方案是使用允许您直接指定范围的工具,例如 gnu shuf
shuf -i1-10 -n1
如果你想使用$RANDOM,将0...32767中的最后8个数字扔掉会更精确,并将其视为0...32759,因为取0...32767 mod 10 你得到以下分布
0-8 each: 3277
8-9 each: 3276
所以,稍微慢一点但更精确
while :; do ran=$RANDOM; ((ran < 32760)) && echo $(((ran%10)+1)) && break; done
【讨论】:
/bin/sh,即使该问题要求 bash。 shuf 技术似乎在 bash 和 sh 中都有效。
要使用 bash 生成随机数,请使用 $RANDOM 内部 Bash 函数。请注意,不应使用 $RANDOM 来生成加密密钥。 $RANDOM 是使用您当前的进程 ID (PID) 和当前时间/日期生成的,该时间/日期由自 1970 年以来经过的秒数定义。
echo $RANDOM % 10 + 1 | bc
【讨论】:
date +%s 来获取大数。 echo $(date +%s) % 4 | bc
echo 只是打印字符串(变量替换发生在命令处理之前,所以 $RANDOM 已经被替换为整数),bc 是实际评估它的当| 将标准输出从echo 重定向到bc 的标准输入
你也可以使用 /dev/urandom:
grep -m1 -ao '[0-9]' /dev/urandom | sed s/0/10/ | head -n1
【讨论】:
sed s/0/10/!
在范围内生成:{0,..,9}
r=$(( $RANDOM % 10 )); echo $r
在范围内生成:{40,..,49}
r=$(( $RANDOM % 10 + 40 )); echo $r
【讨论】:
这是 $RANDOM 和 /dev/urandom 都不可用时的伪随机生成器示例
回显 $(日期 +%S) | grep -o .$ | sed s/0/10/
【讨论】: