各行を読む - BASH

各行を読む - BASH

私の目標は、各リーフライン(実際には各ルール)を配列に保存することです。私の結果:

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]')

具体的なユースケースはわかりませんが、各チェーンを一度に照会する場合は、行番号を削除したり、連想配列のキーとして使用したりすることもできますが、含めることをお勧めします。

thatを使用したくないが、grepまだ配列から最初の2行を除外したい場合は、次のように事実の後ろの最初の2つの要素をオフにできます。

array=("${array[@]:2}")

また、元の例では、次の点に注意してください。

echo "${array[@]}"

別の配列キーにあるかどうかに関係なく、すべてを1行に配置します。行ごとに正確に1つの要素を持つ配列を表示するより良い方法は次のとおりです。

for rule in "${array[@]}"; do echo LINE: "$rule"; done

おすすめ記事