实际上,这是针对 redis 集群的,我有 3 个主 ip 和 3 个从 ip,需要生成 3 对 IP 地址,其中对中的地址位于不同的 /24 子网中。
或者换句话说,给定一个n
IP 地址列表(n
为偶数,并且不超过一半的 IP 地址位于同一/24
子网中),如何将它们分成n
/2 对,其中每对中的两个地址位于不同的 /24 子网中?
这些对应存储为ip_map
关联数组的键和值。例如,给定一个存储在数组中的 IP 地址列表$ips
:
ips=(
"172.211.91.63"
"172.211.90.61"
"172.211.91.30"
"172.211.90.173"
"172.211.89.233"
"172.211.89.166"
)
结果可能是:
declare -A ip_map=(
[172.211.91.63]=172.211.90.61
[172.211.91.30]=172.211.89.233
[172.211.90.173]=172.211.89.166
)
直观地讲,我认为如果你将 IP 地址分类到存储桶中,每个子网一个,然后从 2 个最满的存储桶中挑选 2 个,这样就可以将它们全部配对。可能如下所示:
您的样本给出了:
code for @ARGV
-e
使用默认变量作为循环变量,循环遍历内联脚本 (xpression) 所给定的参数$_
。 的缩写形式为for (@ARGV) {code}
。s/\.\d+$//r
$_
(默认情况下起作用)删除.<digits>
末尾的部分,但使用r
标志,结果将r
被返回而不是存储回$_
。因此,这扩展到 IP 地址的 /24 子网部分。%s
关联数组(又名中的哈希perl
),其中$s{subnet}
是该子网中 IP 地址列表的引用。@{that}
取消引用它,以便我们可以将push
IP 地址($_
)放到列表中。@l = values %s
:获取哈希的值,即将我们的存储桶列表的引用放入@l
列表中。@$b <=> @$a
,它会扩展为其中元素的数量,因此我们比较列表的长度来对它们进行排序)然后pop
从第一个和第二个列表中 ping 一个(pop(@{$l[...]})
)。您可以在 bash 中评估输出(使用
source <(that-code)
或eval "$(that-code)"
),但您不妨将其用于perl
整个过程,因为 shell(尤其是 bash)在编程方面不是很好。如果我必须使用 shell,我会使用 zsh 而不是 bash,其中等效的内容可能如下所示:
zsh 关联数组,与 bash 一样不能包含列表,这里我们将 IP 地址列表以空格分隔(因此我们
(w)
稍后可以使用基于 ord 的索引)存储在关联数组的值中,并以一串x
s 为前缀(有点像 𝍩 𝍪 𝍫 𝍬 𝍸 计数标记),每个 IP 地址一个,因此看起来像:因此,
${(O)l}
我们用来O
按逆序对列表进行排序的 按照元素数量进行排序。pingpop
是通过提取和删除这些存储桶中的最后一个 IP 地址并x
从开头删除一个 IP 地址来完成的。