BASH,将多项变量传递给函数

时间:2017-04-04 15:07:36

标签: bash function variables scripting arguments

我有一个功能:

function checkConn()
{
    RET=0
    echo "in function: ${2}"
    echo
    for i in `cat ${1}`
    do
        for p in ${2}
        do
            if nc -dzw 2 ${i} ${p}  2>&1 >/dev/null

等等。

在脚本的“main”主体中,我有以下内容:

PORTS='22 161 162 1521'
checkConn ${FILE} ${PORTS}

FILE是包含IP列表的文件的名称。

当我将PORTS传递给该函数时,只传递第一个项目。我也尝试过双引号。

我把那个“回声”声明确认。它只显示PORTS中的第一个项目,即22。

如何将所有端口传递给此函数,然后遍历每个端口?

2 个答案:

答案 0 :(得分:2)

最佳做法是将端口列表作为单独的参数传递,每个参数都有自己的argv条目 - 如下所示:

checkConn() {
  file=$1; shift  ## read filename from $1, then remove it from the argument list

  while IFS= read -r address; do
    for port; do  ## we shifted off the filename so this only iterates over ports
      if nc -dzw 2 "$address" "$port" </dev/null >/dev/null 2>&1; then
        echo "$address $port OPEN"
      else
        echo "$address $port CLOSED"
      fi
    done
  done <"$file"
}

file=addrs.txt
ports=( 22 161 162 1521 )
checkConn "$file" "${ports[@]}"

注意:

  • 用于定义函数实际上不需要function关键字;它使您的代码与POSIX sh不兼容,但与可移植语法相比没有任何好处。避免它。
  • BashFAQ #1中详细描述了while IFS= read -r成语。另请参阅Don't Read Lines With For
  • the BashGuide中描述了ports=( ... )"${ports[@]}"语法中使用的数组。

答案 1 :(得分:1)

多种语法违规和过时的结构,你可能需要像

这样的东西
function checkConn() {
    # define variables as local unless you are using it beyond the scope
    # of the function and always lower-case variable names 
    local ret=0
    printf "%s\n" "$2"

    # Splitting the string into an array so that it can be accessed 
    # element wise inside the loop. The -a option in read stores the  
    # elements read to the array
    read -ra portList <<<"$2"     

    # Input-redirection of reading the file represented by argument $1
    # representing the file name. The files are read one at a time    
    while IFS= read -r line; do
        # Array values iterated in a for-loop; do the action
        # for each value in the port number
        for port in "${portList[@]}"; do
            if nc -dzw 2 "$line" "$port"  2>&1 >/dev/null; then
                printf "%s %s\n" "$line" "$port"
                # Your rest of the code
            fi
        done
    done < "$1"
}

并将该函数调用为

ports='22 161 162 1521'
filename="file"
checkConn "$filename" "$PORTS"