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

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

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


当前回答

如果你需要大于15位的范围,不要使用慢的不安全的过时的15位RANDOM,使用快速安全的32位SRANDOM。

SRANDOM自2021年bash 5.1推出以来可用。

Bash 5.1中值得注意的一个有趣的添加是新的SRANDOM变量。SRANDOM变量提供来自系统熵引擎的随机数据,不能被重新播种。特别是,SRANDOM变量提供了一个32位随机数,它依赖于getrandom/getentropy——如果必要的话,还可以回退到/dev/urandom或arc4random,甚至在此之后的另一个回退。”

来源:https://www.phoronix.com/news/gnu - bash - 5.1

看看bash中的RANDOM和SRANDOM有什么不同:

Bash中RANDOM和SRANDOM的区别

请随意改进这个答案。

其他回答

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

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

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

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

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

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

如果您不是bash专家,并希望将此转换为基于linux的bash脚本中的变量,请尝试以下方法:

VAR=$(shuf -i 200-700 -n 1)

这样算上VAR,你的投资范围在200到700美元之间。

你可以这样做

cat /dev/urandom|od -N2 -An -i|awk -v f=2000 -v r=65000 '{printf "%i\n", f + r * $1 / 65536}'

如果需要更多详细信息,请参阅Shell脚本随机数生成器。

在Mac OS X和FreeBSD上,你也可以使用jot:

jot -r 1  2000 65000