如何将数组作为参数传递给bash函数?

注意:在Stack Overflow上找不到答案后,我自己发布了一个有点粗糙的解决方案。它只允许传递一个数组,并且它是参数列表的最后一个元素。实际上,它根本没有传递数组,而是传递数组元素的列表,这些元素被called_function()重新组装成一个数组,但它对我来说是有效的。如果有人知道更好的方法,请在这里添加。


当前回答

只是添加到接受的答案,因为我发现如果数组内容是这样的,它就不能很好地工作:

RUN_COMMANDS=(
  "command1 param1... paramN"
  "command2 param1... paramN"
)

在这种情况下,数组的每个成员都被分割,所以函数看到的数组等价于:

RUN_COMMANDS=(
    "command1"
    "param1"
     ...
    "command2"
    ...
)

为了让这种情况工作,我发现的方法是将变量名传递给函数,然后使用eval:

function () {
    eval 'COMMANDS=( "${'"$1"'[@]}" )'
    for COMMAND in "${COMMANDS[@]}"; do
        echo $COMMAND
    done
}

function RUN_COMMANDS

只是我的2©

其他回答

注:这是我在Stack Overflow上找不到答案后自己发布的粗略的解决方案。它只允许传递一个数组,并且它是参数列表的最后一个元素。实际上,它根本没有传递数组,而是传递数组元素的列表,这些元素被called_function()重新组装成一个数组,但它对我来说是有效的。不久之后,Ken发布了他的解决方案,但我把我的保留在这里作为“历史”参考。

calling_function()
{
    variable="a"
    array=( "x", "y", "z" )
    called_function "${variable}" "${array[@]}"
}

called_function()
{
    local_variable="${1}"
    shift
    local_array=("${@}")
}

你可以像这样传递多个数组作为参数:

takes_ary_as_arg()
{
    declare -a argAry1=("${!1}")
    echo "${argAry1[@]}"

    declare -a argAry2=("${!2}")
    echo "${argAry2[@]}"
}
try_with_local_arys()
{
    # array variables could have local scope
    local descTable=(
        "sli4-iread"
        "sli4-iwrite"
        "sli3-iread"
        "sli3-iwrite"
    )
    local optsTable=(
        "--msix  --iread"
        "--msix  --iwrite"
        "--msi   --iread"
        "--msi   --iwrite"
    )
    takes_ary_as_arg descTable[@] optsTable[@]
}
try_with_local_arys

将回声:

sli4-iread sli4-iwrite sli3-iread sli3-iwrite  
--msix  --iread --msix  --iwrite --msi   --iread --msi   --iwrite

编辑/注释:(摘自下面的评论)

descTable和optsTable作为名称传递,并在函数中展开。因此,在作为参数给出时不需要$。 注意,即使用local定义了descTable等,这仍然有效,因为locals对于它们调用的函数是可见的。 !在$ {!1}展开arg 1变量。 声明-a只是使索引数组显式,这不是严格必要的。

传递几个数组作为参数的一个简单方法是使用字符分隔的字符串。你可以这样调用你的脚本:

./myScript.sh "value1;value2;value3" "somethingElse" "value4;value5" "anotherOne"

然后,你可以像这样在你的代码中提取它:

myArray=$1
IFS=';' read -a myArray <<< "$myArray"

myOtherArray=$3
IFS=';' read -a myOtherArray <<< "$myOtherArray"

通过这种方式,你实际上可以传递多个数组作为参数,它不必是最后一个参数。

DevSolar的回答有一点我不理解(也许他有特定的理由这么做,但我想不出一个):他根据位置参数一个元素一个元素地迭代设置数组。

一个更简单的解释是

called_function()
{
  ...
  # do everything like shown by DevSolar
  ...

  # now get a copy of the positional parameters
  local_array=("$@")
  ...
}

这条即使有空格也适用:

format="\t%2s - %s\n"

function doAction
{
  local_array=("$@")
  for (( i = 0 ; i < ${#local_array[@]} ; i++ ))
    do
      printf "${format}" $i "${local_array[$i]}"
  done
  echo -n "Choose: "
  option=""
  read -n1 option
  echo ${local_array[option]}
  return
}

#the call:
doAction "${tools[@]}"