Reputation: 41
I am unclear what I am doing wrong here or is there some type of bash issue?
I am declaring some static sting arrays and interactively building up another array of string values, all to be passed to a bash function. I get corruption of the array values it seems inside the function itself.
add_firewall_rich_rules() {
node_ips="${1}"
swarm_tcp_ports="${2}"
swarm_udp_ports="${3}"
echo "in: ${node_ips[@]}"
echo "in: ${swarm_tcp_ports[@]}"
echo "in: ${swarm_udp_ports[@]}"
for ip in "${node_ips[@]}"
do
for tcp_port in "${swarm_tcp_ports[@]}"
do
rule="'rule family=\"ipv4\" source address=\"$ip\" port protocol=\"tcp\" port=\"$tcp_port\" accept'"
cmd="firewall-cmd --permanent --zone=public --add-rich-rule=$rule"
echo "$cmd"
done
for udp_port in "${swarm_udp_ports[@]}"
do
rule="'rule family=\"ipv4\" source address=\"$ip\" port protocol=\"udp\" port=\"$udp_port\" accept'"
cmd="firewall-cmd --permanent --zone=public --add-rich-rule=$rule"
echo "$cmd"
done
done
}
declare -a swarm_tcp_ports=('2377' '7946' '4789' '8500' '4000')
declare -a swarm_udp_ports=('2377' '7946' '4789')
declare -a node_ips=()
echo "init: ${node_ips[@]}"
echo "init: ${swarm_tcp_ports[@]}"
echo "init: ${swarm_udp_ports[@]}"
node_ip=""
last_node_ip=""
while read -e -p "Enter ip of additional node in the cluster (hit enter twice to stop adding values): " -i "`echo $node_ip |sed 's/[^.]*$//'`" node_ip; do
if [ "$node_ip" == "$last_node_ip" ]; then
break
fi
if [[ $node_ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
node_ips=("${node_ips[@]}" $node_ip)
else
echo "hit return again to stop adding values"
fi
last_node_ip=$node_ip
echo "${swarm_tcp_ports[@]}"
done
if [ "${#node_ips[@]}" -gt 0 ]; then
echo "out: ${node_ips[@]}"
echo "out: ${swarm_tcp_ports[@]}"
echo "out: ${swarm_udp_ports[@]}"
add_firewall_rich_rules ${node_ips[@]} ${swarm_tcp_ports[@]} ${swarm_udp_ports[@]}
fi
From the Terminal:
# ./firewall_add_rich_rule.sh
init:
init: 2377 7946 4789 8500 4000
init: 2377 7946 4789
Enter ip of additional node in the cluster (hit enter twice to stop adding values): 192.168.1.105
2377 7946 4789 8500 4000
Enter ip of additional node in the cluster (hit enter twice to stop adding values): 192.168.1.106
2377 7946 4789 8500 4000
Enter ip of additional node in the cluster (hit enter twice to stop adding values): 192.168.1.
hit return again to stop adding values
2377 7946 4789 8500 4000
Enter ip of additional node in the cluster (hit enter twice to stop adding values): 192.168.1.
out: 192.168.1.105 192.168.1.106
out: 2377 7946 4789 8500 4000
out: 2377 7946 4789
in: 192.168.1.105 192.168.1.106
in: 192.168.1.106 7946 4789 8500 4000
in: 2377 7946 4789
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="tcp" port="192.168.1.106" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="tcp" port="7946" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="tcp" port="4789" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="tcp" port="8500" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="tcp" port="4000" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="udp" port="2377" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="udp" port="7946" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.105" port protocol="udp" port="4789" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="tcp" port="192.168.1.106" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="tcp" port="7946" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="tcp" port="4789" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="tcp" port="8500" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="tcp" port="4000" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="udp" port="2377" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="udp" port="7946" accept'
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.106" port protocol="udp" port="4789" accept'
It seems like the first element from the first array passed into the function is replacing the first element of the next array passed after the function call is made (and i have noticed sometimes the next array as well but not this time).
Upvotes: 0
Views: 264
Reputation: 322
When you pass your arrays to the function, it expands the values.
arr1=( "1" "2" "3" )
arr2=( "a" "b" "c" )
someFunc "${arr1[@]}" "${arr2[@]}"
#same as someFunc "1" "2" "3" "a" "b" "c" "d"
So in your function you should take the name of the arrays rather than expanding them and declaring them as a new array inside your functions.
arrayTest(){
declare -a localArr1=("${!1}")
declare -a localArr2=("${!2}")
//process arrays
}
arr1=( "1" "2" "3" )
arr2=( "a" "b" "c" )
arrayTest "arr1[@]" "arr2[@]"
Upvotes: 2