函数的定义
function 函数名 {
command
}
或者----------------------
函数名 () {
command
}
函数定义完之后并不会自动执行,需要调用才行,好处在于可以写一段功能代码作为函数,有需要就直接调用。定义的时候哪怕出现语法错误也没关系,不调用就不会报错,当然我们写函数最终目的还是为了调用,为了实现某个功能块。
函数的返回值
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值
使用原则:
直接在脚本里定义函数的代码块写函数名即可完成调用


注意:函数名必须是唯一的,如果先定义了一个,再用同样的名称定义第二个,那么第二个会覆盖第一个的功能,所以这里一定要注意不要重名!


注意:调用函数之前,必须先进行定义!就是说函数的调用必须在函数的后面。
在其它函数中嵌套调用函数的情况,不可以直接写函数的值,便面无法识别,可以用反撇号引起来,相当于是调用函数的结果




注意:不一定要在脚本开头就定义函数,只要调用之前定义就可以
案例:最后调用函数,将fun3函数放在其它两个函数中间


案例:使用脚本编写手动安装yum源,需要用到函数的调用

案例:对比函数中添加与不添加return的区别




案例2:测试文件是否存在


在shell脚本中函数的执行并不会开启一个新的子shell,而是仅在当前定义的shell环境中有效,如果shell脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。
在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令local来实现,函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响
shell脚本中变量默认全局有效
local命令:将变量限定在函数内部使用
案例:函数内和函数外定义相同变量


上述脚本中fun1函数内部使用了local命令设置变量num,其作用是将变量num限定在函数内部,fun1函数外部同样定义了变量num,内部变量num和全局变量互不影响。脚本执行先调用了函数fun1,函数内部变量num为10,所以输出10,调完函数,变量num赋值为100,所以有输出100
在shell中,调用函数时可以向其传递参数,在函数体内部,通过$n的形式来获取参数值,例如,$1表示第一个参数,$2表示第二个参数,就是使用位置参数来实现参数传递。
案例:调用函数时输入位置参数


案例:用户输入位置参数


案例:根据用户输入的值,求出奇数和以及偶数和,求和用函数来写


函数自己调用自己
案例1:列出目录内文件列表,目录用蓝色表示,文件显示层级关系


案例2:计算5的阶乘



使用 sh -x 脚本名称 ,来查看执行步骤


数组是存放相同类型数据的集合,在内存中开辟了连续的空间,通常配合循环使用
普通数组: 不需要申明直接定义,下标索引只能是整数
关联数组: 需要用declare -A 申明,否则系统不识别,索引可以是字符串
直接把要加入数组的元素用小括号括起来,中间用空格分开
格式: 数组名=(value0 value 1 value2)
例如:num=(10 20 30 40)
精确的给每一个下表索引定义一个值加入数组,索引数字可以不连续
格式: 数组名=([0]=value [1]=value [2]=value....)
例如:num=([0]=10 [1]=20 [2]=30 [3]=40)
先把要加入数组的元素全部先复制给一个变量,然后引用这个变量加入到数组
格式: 数组=($列表名)
变量= "value0 value1 value2 value3"
例如:
list= "10 20 30 40"
num=($list)
根据下表定义
格式: 数组名[0]="value"
数组名[1]="value"
数组名[2]="value"
例如: num[0]="10"
num[1]="20"
num[2]="30"
获取数组的所有元素的总数

获取数组所有元素的列表内容

根据下标获取数组元素的内容

根据下标获取元素的长度

总结
定义数组最简单的办法就是:num=(10 20 30 40)
读取数组中的全部长度使用:echo ${#num[*/@]}
读取数组中的下标对应的元素长度: echo ${#num[下标]}
读取数组中的全部内容使用:echo ${num[*/@]}
读取数组中的下标对应的元素内容: echo ${num[下标]}
使用for循环。遍历输出数组中的每一个元素


就是将数组中的元素输出的时候,进行指定哪一块元素进行输出。依靠索引进行查找到元素的位置。



删除整个数组

删除数组中单个元素

类似气泡上涌的动作,会将数据的数组从小到大或者从大到小不断的向前移动
基本思想
冒泡排序的基本思想就是对比相邻的两个元素值,如果满足在这里插入图片描述
条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部。
算法思路
冒泡算法有双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少
案例:用冒泡排序对数组元素进行排序(最小数放前面)
注意:此方法是将第一个数和后面的每一个数进行比较,然后第一个数为最小的数,然后第二个数和后面的每一个数进行比较,然后第二个数为倒数第二小的数,依次比较,循环结束,即可完成排序。


案例2:用冒泡排序对数组元素进行排序(最大数放后面)
注意:第一个数个第二数进行比较,大的放第二个数的位置,第二个和第三个数进行比较,大的放第三个数的位置,直到最后一个数为最大数,然后又重新循环。直到循环结束,排序完成。


案例:实现用户输入数组中的元素,然后将数组内容进行降序排列
代码如下:
#!/bin/bash
#定义数组中的元素
i=0
while true
do
read -p "请输入数组中的元素(数字),截止输入stop:" ack
#用户输入的为stop,那就不再进行获取数组元素
if [ $ack = "stop" ];then
break
fi
#将用户输入的变量赋值到数组中
num[$i]=$ack
let i++
done
lh=${#num[*]}
echo "你输入的数组为:${num[*]},长度为:$lh"
#下面进行冒泡排序
for ((i=1;i<${#num[*]};i++))
do
for ((j=0;j<$lh-$i;j++))
do
first=${num[$j]}
b=$[j+1]
sec=${num[$b]}
if [ $first -lt $sec ];then
temp=$first
num[$j]=$sec
num[$b]=$temp
fi
done
done
echo "排序后的数组为:${num[*]}"


函数
数组
数组的定义方式有多种, 最常见的就是函数名=(元素1 元素2 元素3)
查看数组的长度: ${#数组名[*或@]},查看函数的元素内容: ${数组名[*或@]}
数组中元素的赋值,最常用的赋值为: 数组名[下标]=元素值
数组的切片:切片的意思就是将数组元素内容按照设定的内容进行输出
格式:echo ${数组名[*]:下标:需要打印的几个元素值}
例如:将数组内容的第二个元素开始的3个元素输出
echo ${num[*]:1:3}
数组的替换:只是在输出的时候进行替换 (注意:在替换的时候,它找到内容是数组元素中的内容)
格式:echo ${[*]/匹配的内容/替换后的内容} (仅替换每个元素的第一个匹配项)
例如:将输入中的内容3换成10
echo ${num[*]/3/10}