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

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


当前回答

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

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

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

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

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

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

其他回答

要求:在数组中查找字符串的函数。 这是DevSolar解决方案的一个轻微简化,因为它使用传入的参数而不是复制它们。

myarray=('foobar' 'foxbat')

function isInArray() {
  local item=$1
  shift
  for one in $@; do
    if [ $one = $item ]; then
      return 0   # found
    fi
  done
  return 1       # not found
}

var='foobar'
if isInArray $var ${myarray[@]}; then
  echo "$var found in array"
else
  echo "$var not found in array"
fi 

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[@]}"

你也可以用数组创建一个json文件,然后用jq解析这个json文件

例如:

my-array.json:

{
  "array": ["item1","item2"]
}

script.sh:

ARRAY=$(jq -r '."array"' $1 | tr -d '[],"')

然后像这样调用脚本:

script.sh ./path-to-json/my-array.json

您可以在这个类似的问题中找到更多的想法:如何将数组作为参数传递给Bash中的函数

尽管它很丑,但这里有一个变通方法,只要你没有显式地传递一个数组,而是一个对应于数组的变量:

function passarray()
{
    eval array_internally=("$(echo '${'$1'[@]}')")
    # access array now via array_internally
    echo "${array_internally[@]}"
    #...
}

array=(0 1 2 3 4 5)
passarray array # echo's (0 1 2 3 4 5) as expected

我相信有人可以提出一个更清晰的思想实现,但我发现这是一个更好的解决方案,而不是传递一个数组作为“{array[@]”},然后在内部使用array_inside=(“$@”)访问它。当存在其他位置/getopts参数时,这就变得复杂了。在这些情况下,我必须首先确定,然后使用shift和数组元素删除的某种组合来删除与数组不关联的参数。

纯粹主义者可能会认为这种方法违反了语言,但从实用主义的角度来说,这种方法为我省去了很多痛苦。在一个相关的主题中,我还使用eval将一个内部构造的数组赋值给一个根据我传递给函数的参数target_varname命名的变量:

eval target_varname =美元”($ {array_inside[@]})”

希望这能帮助到一些人。