繁体   English   中英

Bash将数组传递给函数

[英]Bash Pass Arrays to Function

我不清楚我在这里做错了什么,还是有某种bash问题?

我声明了一些静态字符串数组,并交互式地构建了另一个字符串值数组,所有这些都将传递给bash函数。 我发现函数本身内部的数组值损坏。

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

从终端:

# ./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'

似乎传递给函数的第一个数组中的第一个元素正在替换进行函数调用后传递的下一个数组中的第一个元素(而且我有时也注意到下一个数组,但这次没有。)

当您将数组传递给函数时,它会扩展值。

arr1=( "1" "2" "3" )
arr2=( "a" "b" "c" )

someFunc "${arr1[@]}" "${arr2[@]}"

#same as someFunc "1" "2" "3" "a" "b" "c" "d"

因此,在函数中,您应该使用数组的名称,而不是扩展它们并将它们声明为函数内的新数组。

arrayTest(){
    declare -a localArr1=("${!1}")
    declare -a localArr2=("${!2}")

    //process arrays
}

arr1=( "1" "2" "3" )
arr2=( "a" "b" "c" )

arrayTest "arr1[@]" "arr2[@]"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM