目录
一.函数
1.函数的简介
2.函数具有的几个要素
3.定义函数
4.调用函数
5.传递参数
6.函数返回值
7.函数的变量作用范围
8.函数递归
9.查看函数
二.数组
1.数组简介
2.定义数组
3.数组索引
4.数组替换
一.函数
1.函数的简介
在Shell脚本中,函数是一种用于组织和重用代码的机制,它们可以帮助您将脚本分解为更小的、可管理的部分。Shell脚本中的函数与其他编程语言中的函数类似,但在语法和用法上有一些特殊之处。
2.函数具有的几个要素
(1)函数名称: 用于标识函数的名称,其他部分通过这个名称来调用函数。
(2)参数列表: 函数可以接受零个或多个参数,这些参数可以是输入函数的数据或信息。
(3)函数体: 包含了函数执行的代码块,它定义了函数的行为和逻辑。
(4)返回值: 函数执行完毕后可能会返回一个值给调用它的代码,这个值可以用于后续的操作。
3.定义函数
在脚本中通过 function
关键字或者直接使用函数名来定义函数。函数定义可以在脚本的任何位置,但通常会在脚本的开头或者需要调用的地方定义。
# 使用 function 关键字定义函数
function my_function () {
# 函数体,包含需要执行的命令
echo "This is my function"
}
# 或者直接使用函数名定义函数
my_other_function() {
# 函数体
echo "This is my other function"
}
4.调用函数
在脚本中通过函数名和参数列表来调用函数。调用函数时,Shell会执行函数定义中的命令
5.传递参数
函数可以接受参数,这些参数可以在函数体内使用。在Shell脚本中,参数可以通过 $1
, $2
, $3
, ... 来访问,依次代表第一个、第二个、第三个参数,以此类推。
示例
# 定义带参数的函数
greet() {
echo "Hello, $1!"
}
# 调用函数并传递参数
greet "Alice"
6.函数返回值
函数可以通过 return
语句返回一个退出状态码。在Shell中,默认情况下,函数的返回值是函数中最后一个执行的命令的退出状态码。如果需要,可以使用 return
显式地指定返回值。
使用原则
(1)函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
(2)退出状态码必须是0~255,超出时值将为除以256取余
示例:
(1)退出状态码在范围内时
# 定义带返回值的函数
get_sum() {
local sum=$(( $1 + $2 ))
return $sum
}
# 调用函数并获取返回值
get_sum 10 20
echo "Sum is: $?"
(2)退出状态码超出范围
解决方法:
在函数体内实验echo输出,在函数体外使用变量赋值
7.函数的变量作用范围
(1)函数在shell脚本中仅在当前的shell环境中有效
(2)shell脚本中函数的变量默认全局有效
(3)将变量限定在函数内部使用local命令
示例:
(1)变量全局有效
(2)使用local命令
8.函数递归
函数递归是指一个函数在其定义中调用自身的过程。这种方式通常用于解决可以被分解为相似子问题的问题,每次递归调用都会使问题规模减小,直到达到基本情况(终止条件)为止。
递归函数通常包括两个部分:
-
基本情况(终止条件):递归函数中的基本情况是停止递归的条件。当满足基本情况时,递归将不再继续,而是返回一个特定的值。这是递归的出口。
-
递归步骤:递归函数中的递归步骤是函数调用自身的部分。在每次递归调用中,问题的规模都会减小,直到达到基本情况为止。
在编写递归函数时,需要注意以下几点:
- 确保存在基本情况,以避免函数陷入无限循环。
- 确保每次递归调用都朝着基本情况逼近,以确保算法能够终止。
- 考虑递归的性能,因为递归可能会导致函数调用的层级过深,从而消耗大量的内存空间和处理时间。
示例:
计算阶乘
fact() {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[$1 - 1]
local result=$(fact $temp)
echo $[$1 * $result]
# 5 * $result(4*$result(3*$result(2*$result(1))))
fi
}
read -p "请输入:" n
result=$(fact $n)
echo $result
9.查看函数
使用declare -F命令
二.数组
1.数组简介
数组是一种数据结构,用于存储相同类型的元素的集合。它们通常具有固定的大小,这意味着一旦创建,它们的大小就不能改变。数组的元素可以通过索引访问,索引通常从 0 开始,依次递增。数组可以在内存中连续存储,因此可以通过索引快速访问元素,这使得数组在许多场景下都是高效的数据结构。
数组可以是单维的,也可以是多维的。单维数组是最简单的形式,它只包含一个维度,每个元素由一个索引唯一标识。多维数组是数组的数组,其中每个元素本身又是一个数组。例如,二维数组是一个表格或矩阵,可以通过两个索引来访问元素。
数组在编程中有广泛的应用,常见的编程语言都支持数组,包括但不限于 C、C++、Java、Python、JavaScript 和 Shell 脚本等。数组提供了一种方便的方式来组织和处理大量数据,例如存储学生成绩、处理图像像素、表示游戏地图等。
然而,数组的大小通常是固定的,这意味着在使用过程中需要注意数组越界的问题。另外,数组的插入和删除操作可能会比较耗时,因为需要移动其他元素以保持数组的连续性。
2.定义数组
在大多数编程语言中,数组可以通过直接声明来创建,或者通过构造函数或字面量初始化。
定义数组格式:
(1)数组名=(value0 value1 value2 value3 ......)
(2)数组名=([0]=value [1]=value1 [2]=value2 ....)
(3)列表名="value0 value1 value2 value3 ...... "
数组名=($列表名)
(4)数组名[0]="value1"
数组名[1]="value2"
数组名[2]="value3"
3.数组索引
数组中的每个元素都有一个唯一的索引,用于访问该元素。索引通常从 0 开始,逐个递增。
示例:
4.数组替换
[1]为下标,下标默认为起始位为0
数组的定义使用示例脚本:
#!/bin/bash
# 定义一个名为 fruits 的数组
fruits=("apple" "banana" "orange" "grape")
# 打印数组中的所有元素
echo "所有水果: ${fruits[@]}"
# 打印数组的长度
echo "水果数量: ${#fruits[@]}"
# 访问数组中的单个元素(通过索引)
echo "第一个水果: ${fruits[0]}"
echo "第三个水果: ${fruits[2]}"
# 添加新元素到数组末尾
fruits+=("pear")
echo "添加梨后的所有水果: ${fruits[@]}"
# 删除数组中的元素
unset fruits[1]
echo "删除香蕉后的所有水果: ${fruits[@]}"
# 循环遍历数组中的所有元素
echo "遍历所有水果:"
for fruit in "${fruits[@]}"; do
echo "$fruit"
done