Bash - 数组作为参数

时间:2018-01-12 13:17:33

标签: bash

我在使用数组作为参数时遇到问题。

#!/usr/bin/env bash

function array_param
{
  local ARRAY_s; local ARRAY_t; local OPTIND

  while getopts 's:t:' opt ; do
    case "$opt" in
      s) ARRAY_s=$OPTARG;;
      t) ARRAY_t=$OPTARG;;      
    esac
  done
  shift $((OPTIND-1))
  echo "ARRAY_s=${ARRAY_s[@]}; ARRAY_t=${ARRAY_t[@]}"
}

array_s=(100 200 300)
array_t=(0 10 3585)

array_param -s ${array_s} -t ${array_t}

为什么只有第一个元素分配给变量ARRAY_s和ARRAY_t?

  

结果:   ARRAY_s = 100; ARRAY_t = 0

3 个答案:

答案 0 :(得分:1)

稍微修改函数(对变量使用小写,并使用数组语义)

array_param() {
    local l_array_s l_array_t OPTIND

    while getopts 's:t:' opt ; do
        case "$opt" in
        s) l_array_s+=( "$OPTARG" ) ;;
        t) l_array_t+=( "$OPTARG" ) ;;
        esac
    done
    shift $((OPTIND-1))
    echo "l_array_s=${l_array_s[*]}; l_array_t=${l_array_t[*]}"
}

可以称为

array_param "${array_s[@]/#/-s}" "${array_t[@]/#/-t}"
  • ${array_s[@]/#/-s}符号特定于bash,#匹配字符串的开头,并由-s替换为数组中的每个元素。

在printf之后了解如何传递参数

printf "<%s> " "${array_s[@]/#/-s}" "${array_t[@]/#/-t}"

也比较

printf "<%s> " "${array_s}"
printf "<%s> " "${array_s[@]}"
printf "<%s> " "${array_s[*]}"

答案 1 :(得分:0)

${array_s}相当于${array_s[0]},这就是为什么只分配了第一个元素:

#!/usr/bin/env bash

array_param() {   
    local opt OPTIND tmp
    local -a arr_s arr_t

    while getopts 's:t:' opt; do
        case $opt in
            s) tmp=$OPTARG[@]; arr_s=("${!tmp}") ;;
            t) tmp=$OPTARG[@]; arr_t=("${!tmp}") ;;
        esac
    done
    echo "arr_s = ${arr_s[*]}"
    echo "arr_t = ${arr_t[*]}"
}

arr1=(100 200 300)
arr2=(0 10 3585)

array_param -s arr1 -t arr2
  • local opt:您应该对所有变量进行本地化,甚至是opt
  • tmp=$OPTARG[@]:创建此格式的临时变量:array_name[@]
  • arr=(values):数组作业
  • ${!tmp}variable indirection。它首先扩展为$tmp的值,然后再次展开到最终结果:${!tmp} -> ${array_name[@]} -> all values

您还可以使用nameref(使代码更具可读性,但需要bash 4.3或更高版本):

s) local -n tmp=$OPTARG; arr_s=("${tmp[@]}") ;;
t) local -n tmp=$OPTARG; arr_t=("${tmp[@]}") ;;

答案 2 :(得分:0)

您无法将array_sarray_t作为数组传递,getopts只会获得每个数组的第一个元素。

但是,您可以尝试使用C风格的for循环来增加本地ARRAY_sARRAY_t变量,最后将它们打印出来:

    $ cat optarg.sh 
    #!/usr/bin/env bash

    function array_param
    {
      local OPTIND

      while getopts 's:t:' opt ; do
        case "$opt" in
            s) ARRAY_s+=("${OPTARG}");;
            t) ARRAY_t+=("${OPTARG}");;      
        esac
      done
      shift $((OPTIND-1))
    }

    array_s=(100 200 300)
    array_t=(0 10 3585)

    #Works if only array_s length equal array_t length.
    for ((args=0; args<${#array_s[@]}; args++))
    do
        array_param -s ${array_s[args]} -t ${array_t[args]}
    done

    echo "ARRAY_s=${ARRAY_s[@]}; ARRAY_t=${ARRAY_t[@]}"

输出:

ARRAY_s=100 200 300; ARRAY_t=0 10 3585