Veja como eu faria isso. Primeiro, por simplicidade, vamos listar cada uma das cadeias individualmente, já que estou supondo que você queira saber a que cadeia uma regra pertence:
$ 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
Você pode obter uma lista de nomes de cadeias como este:
CHAINS="$(iptables -L | awk '/Chain /{print $2}')"
Agora, vamos usar alguns truques para simplesmente colocá-los em uma matriz:
# 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]'))'
Com o Bash 4, você também pode usar o mapfile
builtin :
IFS=$'\r\n' mapfile INPUT_RULES < <(iptables -L INPUT --line-numbers | grep '^[0-9]')
Agora, não sei seu caso de uso específico, mas se você consultar cada cadeia, uma por vez, também poderá remover os números de linha ou usá-los como chaves em uma matriz associativa, mas talvez eles está tudo bem sendo incluído.
Se você não quiser usar grep
, mas ainda quiser excluir as duas primeiras linhas da matriz, poderá cancelar os primeiros dois elementos após o fato, assim:
array=("${array[@]:2}")
Observe também que no seu exemplo original:
echo "${array[@]}"
colocará tudo em uma linha, seja em chaves de matriz separadas ou não. Uma maneira melhor de visualizar com precisão o array com um elemento por linha seria:
for rule in "${array[@]}"; do echo LINE: "$rule"; done