shell函数传入数组参数的本质
在学习shell函数时,传入数组作为参数在《Linux命令行与shell脚本编程大全》中讲的很模糊,搜了很多博客也是没有说出本质,只是依样画葫芦,所以这里将我的理解与大家分享。
通俗的用法
由于直接将数组名传入函数中,只会传入数组的第一个元素,所以我们要将数组的所有元素传入函数中。下面是典型用法:
#!/bin/bash
function func1 {
arr=($1)
echo ${#arr[*]}
echo ${arr[*]}
}
arr=(1 2 3)
func1 "${arr[*]}"
一般的理解是这样的:将arr数组作为参数传入func1中时,加了双引号,表示将数组arr转为一个字符串,这样就可整体传入到函数中,然后$1代表了这个字符串,将其括起来,表示将这个字符串转化为了数组,赋给了新的数组,最后显示该数组大小和数组。
其它的用法
#!/bin/bash
function func1 {
arr=($@)
echo ${#arr[*]}
echo ${arr[*]}
}
arr=(1 2 3)
func1 ${arr[*]}
这是《Linux命令行与shell脚本编程大全》中使用的方法,$@可以替换成$*,它们都代表了函数funct1传入的所有参数组成的字符串,所以在主函数中,用括号类型转换为数组,接着输出传入的数组大小和元素。
思考
前两种方法在传入一个数组参数时时一样的,但是在传入多个数组的情况下,第二种用法不会区分多个数组,而会将它当做一个数组。举个例子
#!/bin/bash
function func1 {
arr=($@)
echo ${#arr[*]}
echo ${arr[*]}
}
arr1=(1 2 3)
arr2=(4 5 6)
func1 ${arr1[*]} ${arr2[*]}
它的输出为
6
1 2 3 4 5 6
可以看到我们实际上传入两个数组,但是$@并不会区分这两个数组,而是将两个数组的元素合并在一起,作为一个字符串传入了函数中。
传入数组参数的本质
实际上,在shell中传入数组与传入单个元素并无分别,举个例子
#!/bin/bash
function func1 {
arr=($@)
echo ${#arr[*]}
echo ${arr[*]}
}
arr1=(1 2 3)
arr2=(4 5 6)
func1 1 2 3 4 5 6
func1 ${arr1[*]} ${arr2[*]}
输出为
6
1 2 3 4 5 6
6
1 2 3 4 5 6
可以看到传入数组和直接传入元素是一样的,而如果我们想要传入数组而不是单个元素,就需要将传入的元素进行分组,最常用的就是字符串,将其中的一部分转化为字符串,这样就可以将其作为一个整体也就是数组字符串传入函数中,再在函数中使用圆括号进行类型转换转化为数组进行使用。
接着上面的例子,
#!/bin/bash
function func1 {
arr1=($1)
echo ${#arr1[*]}
echo ${arr1[*]}
arr2=($2)
echo ${#arr2[*]}
echo ${arr2[*]}
}
func1 "1 2" "3 4 5 6"
它的输出为
2
1 2
4
3 4 5 6
我们将上例中的参数1 2 3 4 5 6分为了两个字符串传入了函数,将1 2转化为一个字符串,3 4 5 6转化为另一个字符串,然后在函数中用$1、$2表示这两个字符串,然后用圆括号将其转化为数组,输出其大小和元素。
如何传入多个数组
这就很简单了,只需要将上个例子的(1 2)(3 4 5 6)用变量存起来,然后传入函数即可
#!/bin/bash
function func1 {
arr1=($1)
echo ${#arr1[*]}
echo ${arr1[*]}
arr2=($2)
echo ${#arr2[*]}
echo ${arr2[*]}
}
arr1=(1 2)
arr2=(3 4 5 6)
func1 "${arr1[*])" "${arr2[*])"
func1 "1 2" "3 4 5 6"
它的输出为
2
1 2
4
3 4 5 6
2
1 2
4
3 4 5 6