如何在sh(/ bin/sh,而不是bash)中的0-60之间生成随机数?这是一个卫星箱,没有$RANDOM
变量,和其他货物[cksum,od(od -vAn -N4 -tu4 </dev/urandom)]。sh在范围之间的随机数
我想随机化一个crontab作业的时间。
如何在sh(/ bin/sh,而不是bash)中的0-60之间生成随机数?这是一个卫星箱,没有$RANDOM
变量,和其他货物[cksum,od(od -vAn -N4 -tu4 </dev/urandom)]。sh在范围之间的随机数
我想随机化一个crontab作业的时间。
如果你已经TR,头和/ dev/urandom的,你可以这样写:
tr -cd 0-9 </dev/urandom | head -c 3
然后,你必须使用,其余运营商摆在0-60范围。
如何使用纳秒的系统时间?
date +%N
这不像你需要密码有用的数字在这里。
根据其/bin/sh
它的版本,你可以做:
$((date +%N
%60))
如果它不支持$(())
语法,但你有DC ,你可以尝试:
dc -e `date +%N`' 60 % p'
不知道哪个操作系统的版本/bin/sh
或者什么 工具可用,很难拿出保证正常工作的解决方案。
你有awk吗?你可以调用awk的rand()函数。例如:
awk 'BEGIN { printf("%d\n",rand()*60) }' < /dev/null
我总是得到号码“50” – Adrian 2011-01-12 23:34:40
@Adrian:你必须播种随机数发生器:`awk'BEGIN {srand(); printf(“%d \ n”,rand()* 60)}'`。如果只有一个`BEGIN`子句,则不需要重定向。 – 2011-01-13 04:35:47
value=`od -An -N2 -tu2 /dev/urandom` minutes=`expr $value % 60`
种子将是0和65535之间,这是不的偶数倍的60,所以分钟0-15具有被选择稍大的机会的ob,但差异可能是不重要的。
如果你想做到尽善尽美,用“OD - 一个-N1 -tu1”和循环,直到值小于240
测试与busybox的OD。每当产生数由0开始,但有其他位数大于7
马可的回答会失败,因为它被解释为八进制,我建议:
tr -cd 0-9 </dev/urandom | head -c 4 | sed -e 's/^00*//
特殊的情况下,要处理的任何进一步,例如建立一个范围:
RANDOM=`tr -cd 0-9 </dev/urandom | head -c 4 | sed -e 's/^00*//'`
RND50=$((($RANDOM%50)+1)) // random number between 1 and 50
我知道这个职位是旧的,但建议的答案是不产生均匀无偏的随机数。该接受的答案基本上是这样的:
% echo $(($(tr -cd 0-9 </dev/urandom | head -c 3) % 60))
这个建议的问题是,从/dev/urandom
选择一个3位数,范围为0-999,共1000号。但是,千分之六十不均匀。因此,你会偏向产生0-959,稍微超过960-999。
第二个答案,而创造性的使用纳秒从你的时钟,从相同的偏颇做法受到影响:
% echo $(($(date +%N) % 60))
范围为纳秒是0-999,999,999,为1个十亿的数字。所以,如果你将这个结果除以60,那么你将再次偏向产生0-999,999,959,略多于999,999,960-999,999,999。
所有其余的答案是相同的偏见不均匀的一代。
要生成0-59范围内的无偏差统一随机数(我假设他的意思是,而不是0-60,如果他试图随机化crontab(1)
条目),我们需要强制输出为一个倍数60.
首先,我们将随机生成一个32位的数字从0到4294967295:
% RNUM=$(od -An -N4 -tu2 /dev/urandom | awk '{print $1}')
现在,我们将迫使我们的产品范围为$ MIN之间和4294967295这是一个多60:
% MIN=$((2**32 % 60)) # 16
这意味着:
4294967296 - 16 = 4294967280
4294967280/60 = 71582788.0
换句话说,我的[16,4294967295]范围是60恰好倍数所以,每次我在该范围内产生数字,然后除以60,将同样可能与任何其他号码一样。因此,我有一个无偏差的数字0-59的生成器(如果添加1,则为1-60)。
唯一剩下要做的就是确保我的号码是16到4294967295之间。如果我的数小于16,那么我需要生成一个新的号码:
% while [ $RNUM -lt $MIN ]; do RNUM=$(od -An -N1 -tu2 /dev/urandom); done
% MINUTE=$(($RNUM % 60))
把一切一起复制/粘贴goodnees:
#!/bin/bash
RNUM=$(od -An -N4 -tu2 /dev/urandom | awk '{print $1}')
MIN=$((2**32 % 60))
while [ $RNUM -lt $MIN ]; do RNUM=$(od -An -N1 -tu2 /dev/urandom); done
MINUTE=$(($RNUM % 60))
可惜的是不注日期的工作,没有直流../bin/sh的--help /bin/sh的--help BusyBox的v1.15.3(2010-07- 21 18:00:33 CEST)多方通话二进制 – Adrian 2011-01-12 23:40:16