我的目标是将每条分叶线(实际上是每条规则)存储到一个数组中。我的输出:
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT udp -- 109.224.241.0/24 0.0.0.0/0 udp dpt:5060
2 ACCEPT udp -- 109.224.241.0/24 0.0.0.0/0 udp dpt:4569
3 ACCEPT udp -- 217.14.138.0/24 0.0.0.0/0 udp dpt:5060
4 ACCEPT udp -- 217.14.138.0/24 0.0.0.0/0 udp dpt:4569
5 ACCEPT udp -- 172.30.33.0/24 0.0.0.0/0 udp dpt:5060
6 ACCEPT udp -- 172.30.33.0/24 0.0.0.0/0 udp dpt:4569
7 ACCEPT udp -- 212.11.91.0/24 0.0.0.0/0 udp dpt:5060
8 ACCEPT udp -- 212.11.91.0/24 0.0.0.0/0 udp dpt:4569
9 ACCEPT udp -- 212.11.64.0/19 0.0.0.0/0 udp dpt:5060
10 ACCEPT udp -- 212.11.64.0/19 0.0.0.0/0 udp dpt:4569
11 ACCEPT udp -- 77.240.48.0/20 0.0.0.0/0 udp dpt:5060
12 ACCEPT udp -- 77.240.48.0/20 0.0.0.0/0 udp dpt:4569
13 LOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:4569 LOG flags 0 level 4 prefix "AsteriskHack:"
14 DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:4569
15 LOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:5060 LOG flags 0 level 4 prefix "AsteriskHack:"
16 DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:5060
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
我愿意不是想要限制规则数量。每个链都有几条规则。
我执行代码后:
while IFS='' read line -r || [[ -n "$line" ]]; do
array+=($line)
done < <(iptables -L --line-numbers)
当我回显时,${array[@]}
我的输出是一行可怕的文本,所以我想分隔每一行。实际上我的这个数组的内容由不真实数量的 iptables 规则组成(在 echo 之后${!array[@]}
)
我不知道如何在条件下使叶状行必须具有定义的分隔符(新行)。我不确定我的分隔符是否正确。
谢谢你的回复,M
答案1
我就是这样做的。首先,为了简单起见,让我们单独列出每个链,因为我假设您想知道规则属于哪个链:
$ iptables -L INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT udp -- 109.224.241.0/24 0.0.0.0/0 udp dpt:5060
2 ACCEPT udp -- 109.224.241.0/24 0.0.0.0/0 udp dpt:4569
3 ACCEPT udp -- 217.14.138.0/24 0.0.0.0/0 udp dpt:5060
4 ACCEPT udp -- 217.14.138.0/24 0.0.0.0/0 udp dpt:4569
5 ACCEPT udp -- 172.30.33.0/24 0.0.0.0/0 udp dpt:5060
6 ACCEPT udp -- 172.30.33.0/24 0.0.0.0/0 udp dpt:4569
7 ACCEPT udp -- 212.11.91.0/24 0.0.0.0/0 udp dpt:5060
8 ACCEPT udp -- 212.11.91.0/24 0.0.0.0/0 udp dpt:4569
9 ACCEPT udp -- 212.11.64.0/19 0.0.0.0/0 udp dpt:5060
10 ACCEPT udp -- 212.11.64.0/19 0.0.0.0/0 udp dpt:4569
11 ACCEPT udp -- 77.240.48.0/20 0.0.0.0/0 udp dpt:5060
12 ACCEPT udp -- 77.240.48.0/20 0.0.0.0/0 udp dpt:4569
13 LOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:4569 LOG flags 0 level 4 prefix "AsteriskHack:"
14 DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:4569
15 LOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:5060 LOG flags 0 level 4 prefix "AsteriskHack:"
16 DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:5060
您可以获得这样的链名称列表:
CHAINS="$(iptables -L | awk '/Chain /{print $2}')"
现在,让我们使用一些技巧来简单地将它们放入数组中:
# We can just define the array from the contents of our command
# output, using \r or \n as a field separator.
# We use grep to ignore lines that don't start with a number.
IFS=$'\r\n' GLOBIGNORE='*' command eval 'INPUT_RULES=($(iptables -L INPUT --line-numbers | grep '^[0-9]'))'
对于 Bash 4,您还可以使用mapfile
内置:
IFS=$'\r\n' mapfile INPUT_RULES < <(iptables -L INPUT --line-numbers | grep '^[0-9]')
现在,我不知道您的具体用例,但是如果您一次查询每个链,您还应该能够删除行号或将它们用作关联数组中的键,但也许它们很好包括。
如果您不想使用grep
,但仍想从数组中排除前两行,则可以在事后取消设置前两个元素,如下所示:
array=("${array[@]:2}")
另请注意,在您原来的示例中:
echo "${array[@]}"
会将所有内容放在一行上,无论它是否在单独的数组键中。准确查看每行一个元素的数组的更好方法是:
for rule in "${array[@]}"; do echo LINE: "$rule"; done