这回的问题比较复杂了,不太容易描述清楚,容我慢慢道来……
下面的脚本可以生成5个随机数,但是每次执行生成的随机数是相同的
#!/bin/awk -f
function create(first,last){
choices = last - first + 1
return int(rand()*choices+first)
}
BEGIN{
for(i=0;i<5;i++) {
num = create(1,33)
printf ("%02d\n",num)
}
}
我知道可以加入srand()使用新的种子,变成这样:
#!/bin/awk -f
function create(first,last){
choices = last - first + 1
return int(rand()*choices+first)
}
BEGIN{
srand()
for(i=0;i<5;i++) {
num = create(1,33)
printf ("%02d\n",num)
}
}
不过这个种子和时间有关系,就是说一秒内生成的还是相同的数,比如可以将上述文件保存成6.random_nums.awk并执行:
for ((i=0;i<10;i++));do ./6.random_nums.awk;echo '-------';done
可以看到得到的结果是一样的。
于是我想到了给srand()加参数,使其使用不同的种子,于是改成了下面的脚本:
#!/bin/awk -f
function create(first,last){
choices = last - first + 1
return int(rand()*choices+first)
}
BEGIN{
for(i=0;i<5;i++) {
("cat /dev/urandom | head -c 30 | /usr/bin/base64 " | getline)
#print $0
srand($0)
num = create(1,33)
printf ("%02d\n",num)
}
}
那么第一个问题就出现了:去掉print前面的注释会发现,$0在5次的循环结果是一样的,难道getline这一行没有执行,只执行一次吗?
我假设是这样的,所以将脚本再一次更改为下面这样:
#!/bin/awk -f
function create(first,last){
choices = last - first + 1
return int(rand()*choices+first)
}
BEGIN{
("cat /dev/urandom | head -c 30 | /usr/bin/base64 " | getline)
#print $0
srand($0)
num = create(1,33)
printf ("%02d\n",num)
}
执行的时候通过bash进行循环(当然了,效率会降低,这里只是想找到问题)
for ((i=0;i<10;i++));do ./z.awk;echo '-------';done
这次如果再打开print前面的注释的话可以看到$0已经在变化了,但是似乎srand()使用的参数并没有变化,好像使用的是“$0”这两个字符,而不是变量值……
为了验证,我将脚本再次改成
#!/bin/awk -f
function create(first,last){
choices = last - first + 1
return int(rand()*choices+first)
}
BEGIN{
("cat /dev/urandom | head -c 30 | /usr/bin/base64 " | getline)
sRand=$0
srand(sRand)
num = create(1,33)
printf ("%02d\n",num)
}
的形式,执行后结果大部分是19,少部分不一样,这时候再去掉sRand变量的定义:
#!/bin/awk -f
function create(first,last){
choices = last - first + 1
return int(rand()*choices+first)
}
BEGIN{
("cat /dev/urandom | head -c 30 | /usr/bin/base64 " | getline)
sRand=$0
srand(sRand)
num = create(1,33)
printf ("%02d\n",num)
}
得到的结果全部是19.
也就是说srand(sRand)这一行生效了,但是没有完全生效,而且大部分时候没有生效,这是我的第二个问题,哪里用的不正确吗?
第三个问题回到最开始那个脚本,在内部循环的时候没有使用srand,为什么生成的5个随机数却不相同呢?我最终的目的也是想让这个脚本执行的时候不会生成同样的5个数字。
本帖最后由 mine0 于 2013-8-30 18:29 编辑
分享至: