如何将数组作为参数传递给Bash中的函数

Red*_* Lv 43 arrays bash shell

我们知道,在bash编程中,传递参数的方式是$1...... , $N. 但是,我发现将数组作为参数传递给接收多个参数的函数并不容易.这是一个例子:

f(){
 x=($1)
 y=$2

 for i in "${x[@]}"
 do
  echo $i
 done
 ....
}

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "${a[@]}" $b
f "${a[*]}" $b
Run Code Online (Sandbox Code Playgroud)

如上所述,函数f接收两个参数:第一个分配给x一个数组,第二个分配给y.

f可以通过两种方式调用.第一种方法使用"${a[@]}"第一个参数,结果是:

jfaldsj 
jflajds
Run Code Online (Sandbox Code Playgroud)

第二种方式使用"${a[*]}"第一个参数,结果是:

jfaldsj 
jflajds 
LAST
Run Code Online (Sandbox Code Playgroud)

结果都不如我所愿.那么,有没有人知道如何正确地在函数之间传递数组?

cho*_*oba 69

您无法传递数组,只能传递其元素(即扩展数组).

#! /bin/bash
function f() {
    a=("$@")
    ((last_idx=${#a[@]} - 1))
    b=${a[last_idx]}
    unset a[last_idx]

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f "${x[@]}" "$b"
echo ===============
f "${x[*]}" "$b"
Run Code Online (Sandbox Code Playgroud)

另一种可能是按名称传递数组:

#! /bin/bash
function f() {
    name=$1[@]
    b=$2
    a=("${!name}")

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f x "$b"
Run Code Online (Sandbox Code Playgroud)

  • 请注意,"name"变量的值仅为字符串"x [@]".神奇发生在`$ {!...}` (7认同)
  • @RedLv:只需传递数组的名称并使用带有“!”的参数扩展即可获取数组。 (2认同)
  • 请注意:按名称传递数组 => 按引用传递。被调用函数的任何变化都会改变全局值。此外,不能传递函数本地的数组。 (2认同)

Edo*_*iel 28

您可以通过引用bash 4.3+中的函数传递数组.这可能来自ksh,但语法不同.关键的想法是设置-n属性:

show_value () # array index
{
    local -n array=$1
    local idx=$2
    echo "${array[$idx]}"
}
Run Code Online (Sandbox Code Playgroud)

这适用于索引数组:

$ shadock=(ga bu zo meu)
$ show_value shadock 2
zo
Run Code Online (Sandbox Code Playgroud)

它也适用于关联数组:

$ days=([monday]=eggs [tuesday]=bread [sunday]=jam)
$ show_value days sunday
jam
Run Code Online (Sandbox Code Playgroud)

另请参见declare -n手册页.

  • 如果您的外壳支持,最佳答案。最轻的代码。直截了当。谢谢:> (2认同)

gle*_*man 6

您可以先传递"标量"值.这会简化一些事情:

f(){
  b=$1
  shift
  a=("$@")

  for i in "${a[@]}"
  do
    echo $i
  done
  ....
}

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "$b" "${a[@]}"
Run Code Online (Sandbox Code Playgroud)

此时,您可以直接使用array-ish位置参数

f(){
  b=$1
  shift

  for i in "$@"   # or simply "for i; do"
  do
    echo $i
  done
  ....
}

f "$b" "${a[@]}"
Run Code Online (Sandbox Code Playgroud)