编辑:这已被标记为重复,所以让我解释一下这是如何独特的: 1.这用于循环 2.这应该可以在所有版本的bash中移植
first_array=(1 2 3)
second_array=(4 5 6)
do_stuff () {
_array1=( "$1" )
_array2=( "$2" )
for i in "${_array1[@]}"; do
for i in "${_array2[@]}"; do
echo "$i"
done
done
}
do_stuff "$(echo ${first_array[@]})" "$(echo ${second_array[@]})"
这将输出:
4 5 6
代替:
4
5
6
4
5
6
4
5
6
为什么?如果我不将数组作为参数传递,则效果很好:
_array1=(1 2 3)
_array2=(4 5 6)
do_stuff () {
for i in "${_array1[@]}"; do
for i in "${_array2[@]}"; do
echo "$i"
done
done
}
do_stuff
产生此输出:
4
5
6
4
5
6
4
5
6
我希望能够得到这个结果,但是传递我选择的不同数组,以避免重写类似的函数。
答案 0 :(得分:2)
您的代码有什么问题
echo ${first_array[@]}
打印first_array
的所有元素,并用空格隔开。由于您未引用数组扩展,因此它也将受到单词拆分和文件名扩展的影响!
命令替换"$(...)"
将导致一个单字符串,这要归功于双引号并将字符串"1 2 3"
传递给函数
然后,您将此单个字符串 "1 2 3"
分配给数组_array1=( "$1" )
,这将导致该数组仅包含一个元素
同样的事情也适用于第二个数组。将declare -p _array1 _array2
添加到函数中,以查看两个数组确实仅包含一个字符串:
declare -a _array1=([0]="1 2 3")
declare -a _array2=([0]="4 5 6")
解决方法:
您有一个想法要传递所有要素。如果您只有一个阵列,那将很好地工作。然后,您可以使用arr=( "$@" )
。但是,对于两个数组,问题是您不知道第一个数组有多少个元素。因此,您还需要传递第一个数组的元素数量:
#!/usr/bin/env bash
foo=(1 2 3)
bar=(4 5 6)
do_stuff() {
local -a arr1=( "${@:2:$1}" ) arr2=( "${@:$1+2}" )
declare -p arr1 arr2
}
do_stuff "${#foo[@]}" "${foo[@]}" "${bar[@]}"
此代码使用参数扩展,请参见Bash Reference Manual或这篇出色的wiki.bash-hackers.org文章。
答案 1 :(得分:1)
您可以尝试以下操作:
#!/bin/bash
first_array=(1 2 3)
second_array=(4 5 6)
do_stuff () {
declare -a _array1=("${!1}")
declare -a _array2=("${!2}")
echo "${_array1[@]}"
echo "${_array2[@]}"
}
do_stuff first_array[@] second_array[@]
输出:
$ ./script.sh
1 2 3
4 5 6