1. 变量
1.1. 变量命名规范
- 以字母或下划线开头,剩下的部分可以是:字母、数字、下划线。
- 可以使用小写+下划线或驼峰命名,通常采用小写+下划线的方式。
- 区分大小写,
my_Var
和my_var
是不同的变量。 - 避免空格或特殊符号,如
@
、#
、$
等(Shell会将其解释为特殊操作符)。 - 不能使用bash中的关键字,例如 if,for,while,do 等。
- 不要和系统环境变量冲突。
1.2. 定义变量
直接为变量赋值:
# 语法:变量名=值
# 注意:等号左右两边不能有空格
# 示例:
$ name="pingk"
$ age=18
Bash通过传参的方式定义变量:
# 调用脚本时可以将传入的位置参数定义为变量:./test.sh a1 a2 a3
# 使用 $n 获取第 n 个位置参数值,超过 10 需要用 ${n},如下
$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
# 示例
$ cat test.sh
#!/bin/bash
echo $0
echo $1
echo $2
echo $3
echo $4
echo $5
echo $6
echo $7
echo $8
echo $9
echo ${10}
echo ${11}
echo ${12}
# 运行
$ chmod +x test.sh
$ ./test.sh a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
./test.sh
a1
a2
a3
a4
a5
a6
a7
a8
a9
a10
a11
a12
# 其中,$0 是一个特殊变量,用于获取当前脚本或Shell程序的名称。
# 示例脚本
$ cat test.sh
#!/bin/bash
echo "Script name: $0"
# 直接执行脚本,返回脚本的相对路径或绝对路径+文件名。
$ ./test.sh
Script name: ./test.sh
$ /home/admin/scripts/test.sh
Script name: /home/user/scripts/test.sh
# 通过符号链接执行,返回符号链接的路径+文件名,而非原始脚本路径+文件名。
$ ln -s test.sh link_to_test.sh
$ ./link_to_test.sh
Script name: ./link_to_test.sh
# 在当前shell执行,返回当前Shell的名称(如bash),而非脚本路径+文件名。
$ source test.sh
Script name: bash # 若在bash中运行
Bash1.3. 引用变量
# 先定义
$ name="pingk"
# 再引用
$ echo ${name}
pingk
# 注意:如果是打印百分比,建议使用${变量名}%
$ percent=33
$ echo ${percent}%
33%
Bash1.4. 删除变量
$ x=111
$ echo $x
111
$ unset x
$ echo $x
Bash1.5. 内置特殊变量
脚本参数相关:
$0
、$
{n}:详见 1.2 小结。$#
:获取传递给脚本或函数的参数个数。默认情况下,$#
表示传递给 脚本 的参数数量;在 函数内部,$#
表示传递给该 函数 的参数数量(而不是脚本的参数数量)。$@
:获取所有参数列表,每个参数作为独立的字符串(如"$1" "$2" ...
)。$*
:获取所有参数列表,合并为一个字符串(如"$1 $2 ..."
)。
进程状态相关:
$$
:当前 Shell 进程的 PID(进程 ID)。$!
:最后一个后台运行的进程的 PID。$?
:上一条命令的退出状态码(0 表示成功,非 0 表示错误)。$_
:上一个命令的最后一个参数。
1.6. 变量的作用域
变量的作用域(Scope)是指变量在程序中可被访问的范围或可见性。作用域决定了在代码的哪些部分可以引用某个变量。
局部变量
使用 local 关键字定义在函数内的变量属于局部变量,只能在函数内使用,如下所 示:
#!/bin/bash
# 定义函数
function test(){
local x=111
echo "函数内取变量x的值:$x"
}
# 调用函数
test
echo "函数外取变量x的值:$x" # 无法访问函数内的局部变量
# 输出
函数内取变量x的值:111
函数外取变量x的值:
Bash全局变量
全局变量是指变量在当前的整个Shell进程中都可见。每个Shell进程都有自己的作用域,彼此之间互不影响。在Shell中定义的变量,默认就都是全局变量。即在函数内定义的变量如果没有使用 local 声明也属于全局变量。
#!/bin/bash
x=111
function test(){
y=222
echo "函数内取变量x的值:$x"
echo "函数内取变量y的值:$y"
}
test
echo "函数外取变量x的值:$x"
echo "函数外取变量y的值:$y"
# 输出
函数内取变量x的值:111
函数内取变量y的值:222
函数外取变量x的值:111
函数外取变量y的值:222
Bash2. 常量
相对于变量,常量就是不可以被改变的量,即只能读不能改,所以又称之为只读变量。
常量定义方式:
# 使用 readonly 字段可以将变量定义为只读变量,只读变量的值不能被改变。
$ x=111
$ readonly x
$ readonly y=123
$ x=666
-bash: x: 只读变量
$ y=123
-bash: y: 只读变量
Bash3. 基本数据类型
3.1. 数字类型
# int 整型
# 定义
age=18
# float 浮点型
# 定义
long=3.1
Bash3.2. 字符串
# 在shell中,加了引号的字符就是字符串类型
# 定义
name='pingk'
# 字符串包含空格必须加引号
$ msg="hello world"
$ msg=hello world
-bash: world: 未找到命令
# 连续的字符不加引号包含也是可以的,但还是强烈建议加上引号,更规范。
$ msg=hello
$ echo $msg
hello
# 单引号与双引号是不同的
" " # 弱引用,引号的特殊字符有意义
' ' # 强引用,引号内所有特殊字符都取消意义
$ name="pingk"
$ echo "hello ${name}"
hello pingk
$ echo 'hello ${name}'
hello ${name}
Bash3.3. 数组
=================普通数组=================
# 定义方式一:array=(value1 value2 value3)
fruits=("Apple" "Banana" "Cherry")
# 正向索引
echo ${fruits[1]} # 输出: Banana
# 负向索引
echo ${fruits[-1]} # 输出: Cherry
# 定义方式二:array=([key1]=value1 [key2]=value2 [key3]=value3)
array=([1]=111 [0]="two" [3]=333)
# 正向索引
echo ${array[1]} # 输出: 111
echo ${array[3]} # 输出: 333
# 负向索引
echo ${array[-1]} # 输出: 333
# 定义方式三:利用执行命令的结果设置数组元素:array=($(命令)) 或者 array=(`命令`)
# 该方式会将命令的结果以空格为分隔符切成多个元素然后赋值给数组
ls /root/shell
1.sh test.sh
array2=(`ls /root/shell`)
# 正向索引
echo ${array2[0]} # 输出: 1.sh
echo ${array2[1]} # 输出: test.sh
# 负向索引
echo ${array2[-1]} # 输出: test.sh
# 查看普通数组
declare -a # 查看所有普通数组
declare -a | grep array2 # 查看普通数组 array2
=================关联数组=================
# 声明关联数组 user
declare -A user
user["name"]="Alice"
user["age"]=25
# 关联数组取值只能通过key取到对应的值
echo ${user["name"]} # 输出: Alice
# 查看关联数组数组
declare -A # 查看所有关联数组
declare -A | grep user # 查看关联数组 user
Bash4. 扩展语法
4.1. 获取变量值的长度
# 已知变量 msg='hello world!',请统计出变量中包含的字符数量
# 方法一:
echo ${#msg}
12
# 方法二:
echo $msg | wc -L
12
# 方法三:
echo $msg | awk '{print length}'
12
# 方法四:
expr length "$msg" # length是一个函数,注意因为msg的值有空格,所以$msg必须用引号包含
12
Bash4.2. 对数据进行切片
# 语法
${变量:起始位置:长度}
# 示例
str="Hello World"
echo ${str:6} # 输出 "World"(从索引 6 开始到末尾)
echo ${str:5} # 输出 "World" ,实际上应该输出 空格+World ,此时空格在输出到终端时被shell忽略了,需要加上双引号才能看见空格
echo "${str:5}" # 输出 " World"
echo ${str:0:5} # 输出 "Hello"(从索引 0 开始,取 5 个字符)
echo ${str: -5} # 输出 "World"(倒数第 5 个字符开始向后取值)
# 注意:-5 前面必须有一个空格 ${str: -5},否则会被识别为 ${str:-5}。
echo ${str:-5} # 输出变量的值,变量值为空时输出 5 。
Bash4.3. 对数据删除前后缀
# 删除匹配前缀
str="Hello World"
echo "${str#Hello}" # 输出 " World"(删除前缀 "Hello")
echo ${str#Hello} # 输出 "World"(删除前缀 "Hello",并忽略空格)
# 结合 * 表示非贪婪,默认情况下*是非贪婪
echo ${str#*l} # 输出 "lo World" 删除第一个 l 及以前的字符
# 结合 #* 表示贪婪,尽可能地多“吃”字符
echo ${str##*l} # 输出 "d" 删除最后一个 l 及以前的字符
# 删除匹配后缀
str="Hello World"
echo "${str%World}" # 输出 "Hello "(删除后缀 "World")
# 结合 * 表示非贪婪
echo ${str%l*} # 输出 "Hello Wor"
# 结合 %* 表示贪婪
echo ${str%%l*} # 输出 "He"
Bash4.4. 对数据内容替换
str="Hello World"
echo ${str/World/Shell} # 输出 "Hello Shell"(替换 "World" 为 "Shell")
# 非贪婪,默认
echo ${str/l/L} # 输出 "HeLlo World"
# 贪婪
echo ${str//l/L} # 输出 "HeLLo WorLd"
Bash5. 运算符
5.1. 算数运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现。如下所示:
# 浮点运算
bc
# 整数运算
expr
$(())
$[]
let
Bash常见算数运算符:
- +:加法
- -:减法
- *:乘法
- /:除法
- %:取余
bc 示例:
# bc 命令输出的结果默认情况下保留小数点后面的位数同计算值中小数点后位数最大的值
res=`echo "1 + 1" | bc`
echo $res
2
res=`echo "1.0 + 1" | bc`
echo $res
2.0
res=`echo "1.2 + 1.3" | bc`
echo $res
2.5
res=`echo "5.0 + 3.0" | bc`
echo $res
8.0
res=`echo "3 * 4" | bc`
echo $res
12
# 取整
res=`echo "10 / 4" | bc`
echo $res
2
# 取余
res=`echo "10 % 3" | bc`
echo $res
1
res=`echo "10 ^ 3" | bc`
echo $res
1000
# 可以通过 scale 指定结果保留小数点后多少位
res=`echo "scale=2; 5.0 / 3.0" | bc`
echo $res
1.66
res=`echo "scale=2; 5.0 / 6.0" | bc`
echo $res
.83
Bashexpr 示例:
res=`expr 5 / 3 ` # 不支持浮点计算,运算式不能使用引号
echo $res
1
res=`expr 1 + 1`
2
# 如果是乘法,如需要转义 \*
expr 3 \* 10
30
Bash$(()) 示例:
echo $((1 + 1))
2
echo $((1.0 + 2.0)) # 不支持浮点运算符
-bash: 1.0 + 2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0 + 2.0")
# 注意:
echo $(($num1 + $num2)) # 也可以简写为 echo $((num1+num2))
echo $(((5 - 3) * 2)) # 可以嵌套括号
Bash$[] 示例:
# 用法与$(())相同
echo $[1 + 1] # 不支持浮点运算符
2
Bashlet 示例:
# let 不支持浮点运算,且不能直接输出运算结果,只能赋值
# 运算符之间不能有空格
let res=1+1
echo $res
2
let res=50/5
echo $res
10
# 前自增(先 res 加 1,再赋值给 x)
res=10
let x=++res
echo $x
11
echo $res
11
# 后自增(先赋值给 x,res 再加 1)
res=10
let x=res++
echo $x
10
echo $res
11
Bash5.2. 关系运算符
5.2.1. 数值比较运算符
用于比较 整数。
- -eq:等于 (Equal)。
- -ne:不等于 (Not Equal)。
- -gt:大于 (Greater Than)。
- -lt:小于 (Less Than)。
- -ge:大于等于 (Greater or Equal)。
- -le:小于等于 (Less or Equal)。
示例:
a=10
b=5
if [[ $a -gt $b ]]; then # 中括号内两侧必须要有空格
echo "$a 大于 $b"
fi
BashC 语言风格的数字比较:使用 (()) 。
a=10
b=5
if (( $a > $b )); then
echo "$a 大于 $b"
fi
# > :大于
# >= :大于等于
# < :小于
# <= 小于等于
# == :等于
# != :不等于
Bash5.2.2. 字符串比较运算符
用于比较 字符串。
运算符 | 说明 | 示例:变量 a 为 “abc”,变量 b 为 “def” |
= | 判断两个字符串是否相等,相等返回 true。 | [[ $a = $b ]] 返回 false。 |
!= | 判断两个字符串是否不相等,不相等返回 true。 | [[ $a != $b ]] 返回 true。 |
-z | 判断字符串长度是否为0,为0返回 true。 | [[ -z $a ]] 返回 false。 |
-n | 判断字符串长度是否不为 0,不为 0 返回 true。 | [[ -n “$a” ]] 返回 true。 |
$ | 判断字符串是否不为空,不为空返回 true。 | [[ $a ]] 返回 true。 |
5.2.3. [[ ]] 与 [ ]的区别
[[ ]] 与 [ ] 的用法基本相同,不同的是 [[ ]] 支持通配符(*
、?
)和正则表达式,[ ] 内变量需要加双引号,否则可能报错。同时 [ ] 的兼容性更好,支持 sh、dash
等shell。
推荐优先使用 [[ ]]
,需兼容 POSIX Shell(如 sh)时用 [ ]。
5.3. 逻辑运算符
&&
:逻辑与||
:逻辑或- !:逻辑非
示例:
if [ "$a" -gt 5 ] && [ "$b" -lt 10 ]; then
echo "a > 5 且 b < 10"
fi
Bash5.4. 文件测试运算符
运算符 | 含义 | 示例 |
-e | 文件/目录是否存在 | if [ -e “file.txt” ] |
-f | 是普通文件(非目录/设备) | if [ -f “file.txt” ] |
-d | 是目录 | if [ -d “/tmp” ] |
-r | 文件可读 | if [ -r “file.txt” ] |
-w | 文件可写 | if [ -w “file.txt” ] |
-x | 文件可执行 | if [ -x “script.sh” ] |
-s | 测试文件是否存在且非空(即文件大小 > 0 字节) | if [ -s “file.txt” ] |
-L | 是否符号链接 | if [ -L “/lib64” ] |
6. 输入输出操作
6.1. 标准输入输出
Shell 默认提供三个标准 I/O 流:
文件描述符 | 名称 | 默认设备 | 用途 |
0 | 标准输入(stdin) | 键盘 | 读取输入数据 |
1 | 标准输出(stdout) | 终端 | 输出正常结果 |
2 | 标准错误(stderr) | 终端 | 输出错误信息 |
6.2. 基础输出方式
echo 打印到标准输出
echo "Hello, World!" # 输出到终端
echo "Text" > file.txt # 重定向到文件(覆盖)
echo "More" >> file.txt # 追加到文件
Bashprintf 格式化输出
printf "Name: %s\nAge: %d\n" "Alice" 30
# 输出:
# Name: Alice
# Age: 30
Bash6.3. 基础输入方式
read 从标准输入读取
echo "Enter your name:"shuc
read name # 接收标准输入赋值给变量 name
echo "Hello, $name!"
# 另一种写法
read -p "Enter your name:" name # 接收标准输入赋值给变量 name,-p 显示一个提示信息
echo "Hello, $name!"
Bashread 从文件读取
while read line; do
echo "Line: $line"
done < file.txt # 从文件逐行读取
Bash6.4. 输入输出重定向
命令列表如下:
命令 | 说明 |
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
7. 流程控制
7.1. if 判断
基础语法:
if [ 条件 ]; then
# 条件为真时执行的代码
elif [ 其他条件 ]; then
# 其他条件为真时执行的代码
else
# 所有条件均不满足时执行的代码
fi
# 当分支没有需要执行的代码时省略关键字
if [ 条件 ]; then
# 条件为真时执行的代码
fi
Bash7.2. case 语句
Shell 中的 case
语句是一种多分支选择结构,它允许根据变量的值匹配不同的模式并执行相应的代码块。case
语句比多个 if-elif-else
语句更简洁,特别适合处理多个可能的匹配情况。
基本语法:
case 变量 in
模式1)
命令1
;;
模式2)
命令2
;;
*)
默认命令
;;
esac
# case 开始语句
# 变量 是要匹配的值
# 模式) 是匹配模式
# ;; 表示一个模式块的结束
# *) 是默认情况(类似 else)
# esac 结束语句(case 的反写)
Bash示例:
#!/bin/bash
read -p "请输入1-3之间的数字: " num
case $num in
1)
echo "你输入了1"
;;
2)
echo "你输入了2"
;;
3)
echo "你输入了3"
;;
*)
echo "输入不在1-3范围内"
;;
esac
Bash支持通配符:
*
匹配任意字符?
匹配单个字符[ ]
字符范围
case $file in
*.txt)
echo "这是一个文本文件"
;;
*.jpg|*.png)
echo "这是一个图片文件"
;;
*)
echo "未知文件类型"
;;
esac
Bash7.3. while 循环
基本语法:
while [ condition ]
do
# 要执行的命令
done
Bash示例:
#!/bin/bash
count=1
while [ $count -le 5 ]
do
echo "Count: $count"
count=$((count + 1))
done
# 使用 (( )) 进行算术比较
#!/bin/bash
i=0
while (( i < 5 ))
do
echo "i: $i"
((i++))
done
# 读取文件内容
#!/bin/bash
while read line
do
echo "Line: $line"
done < filename.txt
# 无限循环
#!/bin/bash
while true
do
echo "Press [CTRL+C] to stop.."
sleep 1
done
Bashbreak 和 continue:
break
:退出循环continue
:跳过当前迭代,进入下一次循环
示例:
#!/bin/bash
count=1
while [ $count -le 10 ]
do
if [ $count -eq 5 ]
then
((count++)) # 跳过循环之前需要将计数加一,否则会进入死循环
continue
fi
if [ $count -gt 8 ]
then
break
fi
echo $count
((count++))
done
[root@localhost shell]# . while.sh
1
2
3
4
6
7
8
Bash7.4. for 循环
for 循环是 shell 脚本中另一种常用的循环结构,它用于遍历一系列值(如列表、数组、文件内容或命令输出等)。
基本语法:
for variable in list
do
# 要执行的命令
done
Bash常见用法示例:
# 遍历值列表
#!/bin/bash
for fruit in apple banana orange
do
echo "I like $fruit"
done
# 遍历数字范围
#!/bin/bash
for i in {1..5} # 1到5
do
echo "Number: $i"
done
for i in {1..10..2} # 1到10,步长为2
do
echo "number: $i"
done
# C语言风格的for循环
#!/bin/bash
for ((i=1; i<=5; i++))
do
echo "Count: $i"
done
# 遍历命令输出
#!/bin/bash
for file in $(ls)
do
echo "File: $file"
done
# 遍历数组
#!/bin/bash
colors=("red" "green" "blue")
for color in "${colors[@]}"
do
echo "Color: $color"
done
# 遍历位置参数
#!/bin/bash
for arg in "$@"
do
echo "$arg"
done
# 遍历目录中的文件
#!/bin/bash
for file in /path/to/dir/*
do
if [ -f "$file" ]
then
echo "$file is a regular file"
elif [ -d "$file" ]
then
echo "$file is a directory"
fi
done
# 使用通配符
#!/bin/bash
for script in *.sh
do
echo "Script file: $script"
done
Bashbreak 和 continue 的使用与while 相同。
7.5. select 语句
select
是 shell 脚本中一种特殊的循环结构,主要用于创建简单的文本菜单系统。它是 bash 和 ksh 等 shell 中的功能,不是所有 shell 都支持。
基本语法:
select variable in list
do
# 要执行的命令
# 通常包含 break 语句来退出循环
done
# 工作流程:
# 显示一个带编号的菜单,列出所有选项
# 提示用户输入选择(通常是 PS3 环境变量定义的提示符)
# 将用户选择的值赋给 variable
# 执行循环体中的命令
# 除非遇到 break,否则会继续显示菜单
Bash示例:
#!/bin/bash
PS3="请选择一个水果: "
select fruit in "苹果" "香蕉" "橙子" "退出"
do
case $fruit in
"苹果")
echo "你选择了苹果"
;;
"香蕉")
echo "你选择了香蕉"
;;
"橙子")
echo "你选择了橙子"
;;
"退出")
echo "退出菜单"
break
;;
*)
echo "无效选择"
;;
esac
done
# 示例输出演示:
[root@localhost shell]# . select.sh
1) 苹果
2) 香蕉
3) 橙子
4) 退出
请选择一个水果: 1
你选择了苹果
请选择一个水果: 2
你选择了香蕉
请选择一个水果: 6
无效选择
请选择一个水果: 4
退出菜单
[root@localhost shell]#
Bash8. 函数
8.1. 定义函数
基本语法:
# 定义方式1:省略关键字
function_name() {
# 函数体
commands
[return value]
}
# 定义方式2:
function function_name {
# 函数体
commands
[return value]
}
Bash示例:
#!/bin/bash
# 定义函数
say_hello() {
echo "Hello,world!"
}
# 调用函数
say_hello
Bash8.2. 函数参数
函数可以接收位置参数:$1
, $2
, …, $9
,${10}
等,与脚本传递参数相同。$0
仍然是脚本名称,不是函数名。用法见本篇文章 1.2、1.5 小结内容。
示例:
#!/bin/bash
function test1(){
echo "...start..."
echo $1
echo $2
echo $3
echo "...end..."
}
# 输出
test1 111 222 333 444 555 # 为函数体传参
$ ./b.sh
...start...
111
222
333
...end...
Bash脚本传参与函数传参使用同样的符号 $n ,但获取的值不同。
示例脚本:
#!/bin/bash
# 定义函数
function test(){
echo "============"
echo "函数参数1:$1"
echo "函数参数2:$2"
echo "函数参数3:$3"
echo "============"
}
# 调用函数(无参数)
test
# 调用函数(有参数)
test 111 222 333
echo "============"
echo "脚本参数1:$1"
echo "脚本参数2:$2"
echo "脚本参数3:$3"
echo "============"
Bash示例脚本输出:
[root@localhost shell]# . fun.sh xxx yyy zzz
============
函数参数1:
函数参数2:
函数参数3:
============
============
函数参数1:111
函数参数2:222
函数参数3:333
============
============
脚本参数1:xxx
脚本参数2:yyy
脚本参数3:zzz
============
Bash8.3. 函数的返回值
参数返回,可以显示加:return 返回值,如果不加,将以最后一条命令运行结果,作为返回值。 return 后跟数值 n(0-255)。
显示加 return 示例:
#!/bin/bash
function test(){
echo 111
return 1
echo 222
return 1
echo 333
}
test
# 输出返回值
echo $?
# 输出
111
1
# 函数内部可以有多个 return 字段,但要执行一次函数就运行结束。
# 在 shell 中返回的退出状态码 0 代表 true,非 0 代表 false。
# $? 取到上一条命令的退出状态码(0 表示成功,非 0 表示错误)。
Bash不加 return 示例:
#!/bin/bash
function test(){
echo 111
echo 222
echo 333
xxx # 无效命令运行该命令会报错
}
test
# 输出返回值(最后一条命令运行结果)
echo $?
# 输出
111
222
333
./b.sh:行5: xxx: 未找到命令
127 # 无效命令的退出状态值
Bash注意: return 语句只能返回一个介于 0 到 255 之间的整数,而我们想要返回其他范围外的数据或数据类型则直接使用 echo 输出和而不是使用 return。
示例:
#!/bin/bash
add(){
local sum=$(($1 + $2)) # 局部变量,函数外部不可见
echo $sum # 输出两个数字的和
}
echo "输入两个数字求和"
echo "输入第一个数字: "
read num1
echo "输入第二个数字: "
read num2
echo "两个数字分别为 $num1 和 $num2 !"
add $num1 $num2
# 输出示例
输入两个数字求和
输入第一个数字:
40
输入第二个数字:
10
两个数字分别为 40 和 10 !
50
Bash#!/bin/bash
change_array() {
local arr=("$@")
arr+=( "new1" "new2" "new3" )
echo "${arr[@]}"
}
my_array=(1 2 3)
new_array=($(change_array "${my_array[@]}"))
echo "新数组: ${new_array[@]}"
Bash