要素を削除しながらbash配列を繰り返す方法は?

要素を削除しながらbash配列を繰り返す方法は?

GNU バッシュ、バージョン4.3.42(1)-リリース(arm-openwrt-linux-gnu)

Bash配列を使用してiptablesルールをスクリプト化しようとしています。

$NETIDはネットワークアドレスを作成するために使用されます。たとえば、192.168。10.0/24、192.168。20.0/24など

${NETID[@]}の「i」が次の一時変数($NETID_TMP)を作成しようとしています。削除済み$NETID_TMPから。たとえば、「i」= 10の場合、NETID_TMP =(20 30 40)です。

スクリプト:

    #!/opt/bin/bash
    NETID=(10 20 30 40)
    for (( i=0; i<${#NETID[@]}; i++ )); do
       NETID_TMP=(${NETID[*]})
       unset NETID_TMP[${NETID[i]}]
       iptables -I FORWARD -s 192.168.${NETID[i]}.0/24 -d 192.168.${NETID_TMP[0]}.0/24,192.168.${NETID_TMP[1]}.0/24,192.168.${NETID_TMP[2]}.0/24 -j DROP
    done

結果は次のようになります...

iptables -I FORWARD -s 192.168.10.0/24 -d 192.168.20.0/24,192.168.30.0/24,192.168.40.0/24 -j DROP
iptables -I FORWARD -s 192.168.20.0/24 -d 192.168.10.0/24,192.168.30.0/24,192.168.40.0/24 -j DROP
iptables -I FORWARD -s 192.168.30.0/24 -d 192.168.10.0/24,192.168.20.0/24,192.168.40.0/24 -j DROP
iptables -I FORWARD -s 192.168.40.0/24 -d 192.168.10.0/24,192.168.20.0/24,192.168.30.0/24 -j DROP

ベストアンサー1

netid=(10 20 30 40)

for i in "${netid[@]}"; do
    out="iptables -I FORWARD -s 192.168.$i.0/24 -d "

    for j in "${netid[@]}"; do
        (( i == j )) && continue
        out+="192.168.$j.0/24,"
    done
    out="${out%,} -j DROP"

    printf '%s\n' "$out"
done

このBashスクリプトは

iptables -I FORWARD -s 192.168.10.0/24 -d 192.168.20.0/24,192.168.30.0/24,192.168.40.0/24 -j DROP
iptables -I FORWARD -s 192.168.20.0/24 -d 192.168.10.0/24,192.168.30.0/24,192.168.40.0/24 -j DROP
iptables -I FORWARD -s 192.168.30.0/24 -d 192.168.10.0/24,192.168.20.0/24,192.168.40.0/24 -j DROP
iptables -I FORWARD -s 192.168.40.0/24 -d 192.168.10.0/24,192.168.20.0/24,192.168.30.0/24 -j DROP

二重ループを通して。内部ループは、ループ変数が数値的に外部ループの変数と同じ反復をスキップして所望の効果を生成します。

文字列があれば$out準備は完了ですeval

または、次のことを防ぐにはeval:

netid=(10 20 30 40)

for i in "${netid[@]}"; do
    sarg="192.168.$i.0/24"
    darg=""

    for j in "${netid[@]}"; do
        (( i == j )) && continue
        darg+="192.168.$j.0/24,"
    done
    darg="${darg%,}"

    iptables -I FORWARD -s "$sarg" -d "$darg" -j DROP
done

変数置換は の末尾から削除されるため、${parameter%word}af 末尾のコンマが削除されます。word$parameterdarg="${darg%,}"$darg


コメントで質問後に更新:

bash上記の唯一の特定の点は、配列$netid、文​​字列+=に追加された$darg演算子、およびを使用することです((...))。これをsh次のスクリプトに置き換えることができます($IFSまだデフォルトがあると仮定)。

netid="10 20 30 40"

for i in $netid; do
    sarg="192.168.$i.0/24"
    darg=""

    for j in $netid; do
        [ "$i" -eq "$j" ] && continue
        darg="${darg}192.168.$j.0/24,"
    done
    darg="${darg%,}"

    iptables -I FORWARD -s "$sarg" -d "$darg" -j DROP
done

別の数値リストを挿入するには、$darg代わりに内部ループでそれを使用してください$netid。スペースで区切られた数値文字列でなければなりません。

おすすめ記事