shell函数不能直接接收数组变量,需用"${arr[@]}"传参并在函数内用local arr=("$@")重建数组,支持遍历、索引访问、切片和修改。

Shell 函数本身不能直接接收“数组变量”作为单个参数,因为函数调用时参数会被拆解为位置参数($1、$2…),而数组名(如 arr)单独传入只会展开成第一个元素。但可以通过标准、可靠的方式把数组内容“传递进去”,并在函数内重建为数组——核心是利用 $@ 和括号赋值。
把数组展开后传参,函数内重新组装
这是最常用也最安全的做法:调用时用 ${arr[@]} 展开所有元素,函数内用 local new_arr=("$@") 接收。
- 调用方写法:
myfunc "${arr[@]}"(注意双引号,防止含空格的元素被截断) - 函数内写法:
local data=("$@")—— 这样${data[@]}就还原了原数组 - 可立即获取长度:
local len=${#data[@]}
在函数中安全访问数组元素
重建后的数组支持完整操作,包括遍历、修改、切片:
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统
- 遍历每个元素:
for item in "${data[@]}"; do echo "$item"; done - 按索引读取:
echo "${data[0]}"、echo "${data[-1]}"(最后一个) - 截取子数组:
echo "${data[@]:1:3}"(从下标 1 开始取 3 个) - 修改某项:
data[2]="new_value"(仅影响函数内副本)
避免常见陷阱
几个关键细节不注意就会出错:
- 别写
myfunc $arr—— 没引号且没[@],只传第一个元素,还可能因空格崩坏 - 别在函数里写
local data=($@)(缺引号)—— 含空格或通配符的元素会被二次分割或展开 - 如果还需传其他非数组参数(比如操作类型、阈值),把数组放在最后,并用
shift提前消耗掉固定参数,再用"$@"接收剩余全部
带额外参数的实用示例
比如一个统计函数,接收操作类型(sum/max)和数值数组:
calc() {
local op=$1; shift
local nums=("$@")
local result=0
case $op in
sum)
for n in "${nums[@]}"; do ((result += n)); done
echo $result
;;
max)
[[ ${#nums[@]} -eq 0 ]] && return 1
result=${nums[0]}
for n in "${nums[@]:1}"; do [[ $n -gt $result ]] && result=$n; done
echo $result
;;
esac
}
# 调用:calc sum 10 25 7 33 → 输出 75
# calc max 10 25 7 33 → 输出 33










