文章目录
- 1 函数
- 1.1 函数概述
- 1.1.1 定义和优点
- 1.1.2 函数使用注意事项
- 1.2 函数的相关操作
- 1.2.1 定义函数
- 1.2.2 查看函数
- 1.2.3 调用函数
- 1.2.4 传递参数
- 1.2.5 函数的返回值
- 1.2.6 删除函数
- 1.3 函数的作用范围
- 1.4 函数文件
- 1.5 递归函数
- 1.5.1 函数练习:用递归函数计算正整数的阶乘
- 2 数组
- 2.1 数组概述
- 2.2 数组定义的方法
- 2.3 普通数组和关联数组
- 2.3.1 普通数组
- 2.3.2 关联数组
- 2.4 数组的切片
- 2.5 数组的值如何进行替换
- 2.5.1 临时替换
- 2.5.2 永久替换
- 2.6 删除数组
- 2.7 追加数组中的元素
- 2.7.1 按照索引逐个添加
- 2.7.2 自动补齐添加
- 2.8 向函数内的数组传参
- 2.9 例题
- 2.9.1 例题1:把数组内的每个值*2,然后打印出新的数组
- 2.9.2 例题2:冒泡排序
- 2.9.3 例题3:提取最大值
- 2.9.4 例题4:点名脚本
1 函数
1.1 函数概述
1.1.1 定义和优点
函数将命令序列按格式写在一起,方便重复使用命令序列。
1.1.2 函数使用注意事项
同名函数后一个生效;
调用函数之前先定义函数,如果调用写在定义函数前,则调用无法生效;
每个函数是独立的。
1.2 函数的相关操作
1.2.1 定义函数
方式一(推荐使用)
function_name() {
# 函数体
}
方式二
function function_name {
# 函数体
}
方式三
function function_name() {
# 函数体
}
在函数体中可以编写任意数量的命令和逻辑来实现函数的功能
1.2.2 查看函数
declare -F
#查看所有已定义的函数的函数名declare -F func_name
#查看指定函数的函数名
1.2.3 调用函数
只有定义了函数,才能调用函数
#先定义函数
function_name() {
# 函数体
}#调用函数
function_name
1.2.4 传递参数
在函数调用时传递参数给函数。
在函数体内部通过位置变量来引用传递给函数的参数。
test() {echo "Parameter 1: $1"echo "Parameter 2: $2"
}
test $1 $2
1.2.5 函数的返回值
函数可以通过return
语句设置返回值。
return 从函数中返回,用最后状态命令决定返回值
return 0 无错误返回
return 1-255 有错误返回超过256的值,会和256相除取余数
返回值的作用:
- 对函数执行的结果进行判断和处理:函数可以返回不同的值来表示不同的执行状态或错误情况。
- 传递函数执行的结果给其他部分:函数的返回值可以被赋值给变量,能将函数的计算结果传递给其他命令或者再次使用。
- 作为脚本的退出状态码:根据不同的返回值来设置不同的退出状态码。
1.2.6 删除函数
unset function_name
#从当前的 Shell 环境中删除指定的函数
1.3 函数的作用范围
函数在Shell脚本中仅在当前Shell环境中有效,脚本中的变量默认全局有效。
使用local
命令可以将变量限定在函数内部使用。
1.4 函数文件
将函数代码写入一个脚本文件,在需要的时候调用该脚本文件,相当于直接调用函数。
在Shell脚本中使用函数文件时,需要写上函数文件的绝对路径。
1.5 递归函数
递归归函数是指在函数体内调用自身的函数,用于需要重复执行相同或类似任务的场景。
编写递归函数时要确保设定递归的结束条件,以避免死循环。
1.5.1 函数练习:用递归函数计算正整数的阶乘
#!/bin/bash
# 定义递归函数
fact() {if (( $1 = 1 )); thenecho 1elselocal temp=$(fact $(( $1 - 1 )))echo $(( $1 * $temp ))fi
}# 调用递归函数
read -p "输入一个正整数: " n
result=$(fact $n)
echo "阶乘结果为: $result"
2 数组
2.1 数组概述
就是定义了一系列,可以是整数,字符串,浮点的数的变量值的集合。数组可以一次性定义多个变量值,可以直接从数组当中引用
2.2 数组定义的方法
方法一:一次赋值全部元素
数组名=( value0 value1 value2 value3 ......)
方法二:通过下标值定义每个元素
数组名=([0]=value [1]=value1 [2]=value2 ....)
#[0] [1] [2] 为下标值
下标值和索引值表示相同的意思,即元素在数组中的位置。
数组的下标值从0开始,逐个递增,用于唯一标识数组中的每个元素。
2.3 普通数组和关联数组
2.3.1 普通数组
普通数组(Regular Array)
- 使用连续的整数值作为索引,从0开始递增。
- 声明时使用
declare
或declare -a
命令。 - 元素之间的顺序是固定的,根据索引进行访问。
#示例
fruits=("apple" "banana" "cherry")
echo ${fruits[0]} # 输出: apple
echo ${fruits[1]} # 输出: banana
普通数组使用整数索引访问数组中的元素。
2.3.2 关联数组
关联数组(Associative Array)
- 使用任意字符串作为键来访问和存储元素。
- 声明时使用
declare -A
命令。 - 元素之间的顺序是不固定的,通过键进行访问。
#示例
declare -A ages
ages["Alice"]=25
ages["Bob"]=30
echo ${ages["Alice"]} # 输出: 25
echo ${ages["Bob"]} # 输出: 30
关联数组使用字符串键来标识和存储元素。
2.4 数组的切片
test1=(2 3 5 6 7 8)
echo ${test1[*]}
2 3 5 6 7 8
echo ${test1[*]:0:2} # “0”表示索引位,“2”表示步长,包含其本身
2 3
echo ${#test1[*]}
6 #显示数组元素个数
2.5 数组的值如何进行替换
2.5.1 临时替换
test1=(2 4 6 8 9)
echo ${test1[*]}
2 4 6 8 9
echo ${test1[*]/4/66}
#临时替换
2 66 6 8 9
echo ${test1[*]}
2 4 6 8 9
2.5.2 永久替换
test1=(2 4 6 8 9)
echo ${test1[*]}
2 4 6 8 9
test1=(${test1[*]/4/66})
#永久替换
echo ${test1[*]}
2 66 6 8 9
2.6 删除数组
#删除数组,删除整个数组以及删除数组中的值
unset test1
echo ${test1[*]}# 数组值为空
test1=(2 4 6 8 10)
unset test1[1]
echo ${test1[*]}
2 6 8 10
echo ${test1[1]}# 结果为空值,只是删除该位的值,而不是删除该位
echo ${test1[2]}
6 # 6的索引依然是2,不会往前递补
2.7 追加数组中的元素
2.7.1 按照索引逐个添加
test1=(1 2 3 4)
echo ${test1[*]}
1 2 3 4
test1[4]=5
echo ${test1[*]}
1 2 3 4 5
test1[6]=5
echo ${test1[*]}
1 2 3 4 5 5
echo ${test1[5]}# 该方法不推荐使用,一是因为需要知道数组元素的个数,二是无法自动补齐
2.7.2 自动补齐添加
test1=(1 2 3 4 5)
test1+=(6 7)
echo ${test1[*]}
1 2 3 4 5 6 7
echo ${test1[5]}
6 #自动补齐
echo ${test1[6]}
7
2.8 向函数内的数组传参
test1 () {abc=($(echo $@))echo ${abc[*]}}
abc1=(1 2 3 4 5)
test1 ${abc1[*]}
2.9 例题
2.9.1 例题1:把数组内的每个值*2,然后打印出新的数组
test1 () {abc=($(echo $@))for ((i=0;i<${#abc[*]};i++))doabc[$i]=$((${abc[$i]}*2))doneecho ${abc[*]}
}
abc1=(1 2 3 4 5)
test1 ${abc1[*]}或者test1 () {abc=($(echo $@))for i in ${abc[*]} doi=$(($i*2))a+=($i)doneecho ${a[*]}
}
abc1=(1 2 3 4 5)
test1 ${abc1[*]}
2.9.2 例题2:冒泡排序
算法思路
冒泡算法由双层循环实现。
外部循环用于控制排序轮数,循环次数一般为要排序的数组长度减1次。
因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。
内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。
#把数组内的元素(整数),按照从小到大,或者从大到小的顺序进行排列
abc=(20 10 60 40 50 30)
#循环几次
#位置如何交换
len=${#abc[*]}
for ((i=1;i<$len;i++))
dofor ((k=0;k<$len-i;k++))do
#小的在左边,大的去右边first=${abc[$k]}j=$(($k+1))second=${abc[$j]}if [ "$first" -gt "$second" ]thentemp=$firstabc[$k]=$secondabc[$j]=$tempfi
done
done
2.9.3 例题3:提取最大值
#!/bin/bash
a=( 20 30 60 100 )max=${a[0]}
l=${#a[*]}for ((i=0;i<$l;i++))
do
if [[ $max -lt ${a[$i+1]} ]]
then
max=${a[$i+1]}
fi
done
echo $max
2.9.4 例题4:点名脚本
#!/bin/bash
a=( aa bb cc dd ee ff )
x=${#a[@]}
j=`echo $[RANDOM%$x]`
n=$[ j+1 ]
echo "学号是 $n"
echo ${a[$j]}