我需要从一个shell脚本生成一个2000-65000之间的随机端口号。问题是$RANDOM是一个15位的数字,所以我被卡住了!

如果没有大小限制,PORT=$(($RANDOM%63000+2001))将很好地工作。

有没有人有一个例子,我可以这样做,也许从/dev/urandom提取一些东西,并得到它在一个范围内?


当前回答

生成范围为[$floor,$ceil]的随机数,不依赖:

$(((RANDOM % $(($ceil- $floor))) + $floor))

在2000到65000之间生成100个数字:

for i in $(seq 100); do echo $(((RANDOM % $((65000 - 2000))) + 2000));done

其他回答

在Bash中从10000000000 -999999999999范围内生成50个数字,并将它们保存到文件filename.csv中

shuf -i 100000000000-999999999999 -n 50 -o filename.csv

根据bash手册页,$RANDOM分布在0到32767之间;也就是说,它是一个无符号的15位值。假设$RANDOM是均匀分布的,可以创建一个均匀分布的30位无符号整数,如下所示:

$(((RANDOM<<15)|RANDOM))

因为你的范围不是2的幂,一个简单的模运算几乎只能给你一个均匀的分布,但如果输入范围是30位,输出范围小于16位,就像你的例子一样,这应该足够接近了:

PORT=$(( ((RANDOM<<15)|RANDOM) % 63001 + 2000 ))

ruby也是一样:

echo $(ruby -e 'puts rand(20..65)') #=> 65 (inclusive ending)
echo $(ruby -e 'puts rand(20...65)') #=> 37 (exclusive ending)

你可以通过urandom得到随机数

Head -200 /dev/urandom | cksum

输出:

3310670062 52870

检索上述数字的一部分。

Head -200 /dev/urandom | cksum | cut -f1 -d " "

那么输出是

3310670062

为了满足您的要求,

Head -200 /dev/urandom |cksum | cut -f1 -d " " | awk '{print $1%63000+2001}'

这是另一个。我原以为它对任何东西都适用,但我工作时的centos盒子上没有sort的随机选项。

 seq 2000 65000 | sort -R | head -n 1