我需要在2000-65000
shell脚本之间生成一个随机端口号.问题是$RANDOM
15位数,所以我卡住了!
PORT=$(($RANDOM%63000+2001))
如果不是因为尺寸限制,它会很好地工作.
有没有人有一个如何做到这一点的例子,可能是从/dev/urandom
一个范围内提取并得到它?
shuf -i 2000-65000 -n 1
请享用!
编辑:范围包含在内.
在Mac OS X和FreeBSD上你也可以使用jot:
jot -r 1 2000 65000
根据bash手册页,$RANDOM
分布在0到32767之间; 也就是说,它是一个无符号的15位值.假设$RANDOM
均匀分布,您可以创建一个均匀分布的无符号30位整数,如下所示:
$(((RANDOM<<15)|RANDOM))
由于你的范围不是2的幂,简单的模运算几乎只能给你一个均匀的分布,但是输入范围是30位,输出范围小于16位,就像你的情况一样,这应该足够接近:
PORT=$(( ((RANDOM<<15)|RANDOM) % 63001 + 2000 ))
这是Python的一个
randport=$(python -S -c "import random; print random.randrange(2000,63000)")
和一个与awk
awk 'BEGIN{srand();print int(rand()*(63000-2000))+2000 }'
想到的最简单的一般方法是perl one-liner:
perl -e 'print int(rand(65000-2000)) + 2000'
你总是可以使用两个数字:
PORT=$(($RANDOM + ($RANDOM % 2) * 32768))
你仍然需要剪辑到你的范围.它不是一般的n位随机数方法,但它适用于你的情况,而且它都在bash中.
如果你想要非常可爱并从/ dev/urandom中读取,你可以这样做:
od -A n -N 2 -t u2 /dev/urandom
那将读取两个字节并将它们打印为unsigned int; 你仍然需要剪裁.
这是另一个.我认为它几乎可以用于任何事情,但是我的centos盒子里没有sort的随机选项.
seq 2000 65000 | sort -R | head -n 1
你可以这样做
cat /dev/urandom|od -N2 -An -i|awk -v f=2000 -v r=65000 '{printf "%i\n", f + r * $1 / 65536}'
如果需要更多详细信息,请参阅Shell脚本随机数生成器.
$RANDOM
是0到32767之间的数字。您需要2000到65000之间的端口。这是63001个可能的端口。如果我们将值保持$RANDOM + 2000
在2000到33500之间,则可以覆盖31501个端口。如果我们掷硬币,然后有条件地将31501添加到结果中,我们可以获得更多的端口,从33501到65001。然后,如果我们仅丢弃65001,就可以得到所需的确切覆盖范围,并且所有端口的概率分布均匀。
random-port() { while [[ not != found ]]; do # 2000..33500 port=$((RANDOM + 2000)) while [[ $port -gt 33500 ]]; do port=$((RANDOM + 2000)) done # 2000..65001 [[ $((RANDOM % 2)) = 0 ]] && port=$((port + 31501)) # 2000..65000 [[ $port = 65001 ]] && continue echo $port break done }
测试中
i=0 while true; do i=$((i + 1)) printf "\rIteration $i..." printf "%05d\n" $(random-port) >> ports.txt done # Then later we check the distribution sort ports.txt | uniq -c | sort -r
如果您不是bash专家,并且希望将其转换为基于Linux的bash脚本中的变量,请尝试以下操作:
VAR=$(shuf -i 200-700 -n 1)
这将使您获得200到700的范围$VAR
,包括在内.
与红宝石相同:
echo $(ruby -e 'puts rand(20..65)') #=> 65 (inclusive ending) echo $(ruby -e 'puts rand(20...65)') #=> 37 (exclusive ending)