shell脚本之函数
一、shell函数定义
- 将命令序列按格式写在一起
- 可方便使用命令序列
格式1:
function 函数名 {
命令序列
【return x】 //使用return或exit可以显示地结束函数
}
函数名
格式2:
函数名 () {
命令序列
}
函数名
经典案例:
#调用函数,是从上往下依次执行的
f1 (){
echo hello
}
f3 (){
echo "$(f1) $(f2)"
}
f2 (){
echo world
}
f3
1.1函数注意事项
1.直接写函数中调用
2函数直接写函数名同名函数后一个生效
3.调用函数一定要先定义
4.只要先定义了调用的其他函数定义顺序无关
1.2 函数返回值
return表示退出函数并返回一个退出值
,脚本中可以用 $ ? 变量显示该值
使用原则:
- 1、函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
- 2、退出状态码必须是0~255,超出时值将为除以256取余
案例1:通过return返回一个乘积
案例2:求和
1.3函数调用的方法
示例1:
#!/bin/bash
h () {
echo "hello"
}
w () {
echo "world"
}
nihao () {
h
w
}
h
w
nihao
示例2:
#定义函数
#!/bin/bash
os (){
if grep -i -q "CentOS Linux 7 " /etc/os-release
then
echo "此操作系统是centos 7"
elif grep -i -q "CentOS Linux 6 " /etc/os-release
then
echo "此操作系统是centos 6"
elif grep -i -q "CentOS Linux 8 " /etc/os-release
then
echo "此操作系统是centos 8"
fi
}
#调用函数
os
1.4 函数的传参
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…即使用位置参数来实现参数传递。
示例1:通过位置变量进行求和
#!/bin/bash
add () {
let sum=$1+$2
echo $sum
}
sum $1 $2
1.5 函数的作用范围
- 函数在shell脚本中仅在当前shell环境中有效
- shell脚本中变量默认全局有效
- 将变量限定在函数内部使用local命令
注:
- 函数内部变量通过local来实现
- 通过定义myfun函数,再其内部设置局部变量i
- 函数内部和外部分别赋值,进行结果验证
案例:局部变量与全局变量区别
Local定义变量只能在内部使用
,6是局部的,8是全局的,用来指定变量
。
#!/bin/bash
myfun(){
local i
i=6
echo $i
}
i=8
myfun
echo $i
但是注意了如果没有local i这句话时
,i是全局变量
,当他为全局变量的时候,他是从上往下执行的,系统只承认第一个定义的i的值
,以后所有的i不管在定义为什么都是第一个定义的值。
当没有local i 这句话时,代表他是一个全局。
1.6函数的参数
1.6.1参数的用法
函数名称 参数1 参数2 参数3…
1.6.2参数的表示方法
- $1 2...... 2 ...... 2......${10} ${11}
1.6.3 经典案例:
1.6.3.1 求前一个数与后一个数相乘的结果
#!/bin/bash
jiecheng (){
zhangzhihan=1
for i in {
1..6}
do
let zhangzhihan=$i*$zhangzhihan
echo $zhangzhihan
done
}
jiecheng
1.6.3.2 求1到6的阶乘【注意done的位置】
#!/bin/bash
#求阶乘1到6的阶乘
jiecheng (){
zhangzhihan=1
for i in {
1..6}
do
let zhangzhihan=$i*$zhangzhihan
echo $zhangzhihan
done
}
jiecheng
1.6.3.3 判断是否为文件
#!/bin/bash
file=/home/error.txt
zzh6(){
if [ -f $file ];then #判断是否为文件
return 80
else
return 40
fi
}
zzh6
echo $?
1.7 递归函数
- 调用自己本身的函数
1.7.1 小福袋:
给命令行提示字符加颜色
PS1="\[\e[1;34m\][\u@\h \W]\\$\[\e[0m\] "
PS1="\[\e[1;35m\][\[\e[1;34m\]\u\[\e[1;36m\]@\[\e[1;34m\]\h \[\e[1;31m\]\w\[\e[1;35m\]]\[\e[1;36m\]\\$\[\e[0m\] "
\[\e[1;35m\][ ====> 定义左边的"["
\[\e[1;34m\]\u ====> 定义用户名
\[\e[1;36m\]@ ====> 定义"@"
\[\e[1;34m\]\h ====> 定义第一个点(.)之前的主机名 //34代表文件
\[\e[1;31m]\w ====> 定义目录完整路径
\[\e[1;35m]] ====> 定义"]"
\[\e[1;36m\]\\$ ====> 定义"#"或"$"
\[\e[0m\] ====> 一段不显示字串的结束
1.7.2 经典案例
1.7.2.1 递归显示var下的log里面有哪些是目录
如果是目录就显示为蓝色判断目录下,有哪些目录,打印显示出,不显示文件
[root@localhost ~]# vim zzh7.sh
#!/bin/bash
#列出目录文件的列表,目录可用颜色表示(蓝色表示目录;白色表示文件)文件显示层及关系
list (){
for i in $1/* #$1下面的所有内容
do
if [ -d $i ];then #-d代表是目录 只要是目录的我就用蓝色显示
echo -e "\e[34m$i\e[0m"
#标准格式【】里面的内容是表示颜色 -e表示转义字符标识
echo $i
list $i " $2"
else
echo "$2$i"
fi
done
}
list $1 $2 #调用变量
1.7.2.2 交互式 递归方式计算你输入的数值作为阶乘
#!/bin/bash
#交互式 递归方式计算你输入的数值作为阶乘
#比如我第一次输入5
fun (){
if [ $1 -eq 1 ];then
echo 1
else
#5不等于1执行else的 此时tp=5-1=4;res=4 此时echo为5*4
local tp=$[ $1 - 1 ] #这个是局部
res=$(fun $tp) #相当于直接调用tp本身
echo $[ $1 * $res ] #$1是5
fi
}
read -p "请输入:" num
res=$(fun $num)
echo $res
#执行过程
#fun 5 $1=5 tp=4 res=fun 4 echo 5 * 4() 5*4*3*2*1
#fun 4 $1=4 tp=3 res=fun 3 echo 4 *3(fun) 4*3*2*1
#fun 3 $1=3 tp=2 res=fun 2 echo 3 * 2(fun) 3*2*1
#fun 2 $1=2 tp=1 res=fun 1 echo 2*1(fun) 2*1
#fun 1 $1 echo 1 1
二. 数组
2.1 shell数组的定义
- 数组中
可以存放多个值
。Bash Shell 只支持一维数组(不支持多维数组) - 数组元素的下标
由 0 开始
。 - Shell 数组用
括号
来表示,元素用"空格"符号分割开
- 在shell语句中,使用、遍历数组的时候,数组格式要写成
${arr[@]} 或 ${arr[*]}
数组是存放相同类型数据的集合,在内存中开辟了连续的空间,通常配合循环使用哦!
2.2 数组的分类
普通数组:不需要声明直接定义,下标索引只能是整数
关联数组:需要用declare -A 声明否则系统不识别,索引可以是字符串
2.3 数组的定义方式
2.3.1 方式一
1.直接把要加入数组的元素用小括号括起来
,中间用空格分开
num=(11 22 33 44)
2.3.2 方式二
2.精确的给每一个下标索引定义一个值
加入数组,索引数字可以不连续
num=([0]=55 [1]=66 [2]=77 [3]=88)
2.3.3 方式三
先把要加入数组的元素
全部先赋值给一个变量
,然后引用这个变量加入到数组
list=“11 12 13 14”
num=($list)
2.3.4 方式四
可以把命令的结果用小括号括起来添加到数组
,那么数组会以空格或者制表符区分每一个元素
num=(`cat /etc/passwd`)
[root@localhost ~]# echo ${
#num[*]}
111
[root@localhost ~]# echo ${
num[0]}
root:x:0:0:root:/root:/bin/bash
注意以下特殊方式:
[root@localhost ~]# list[0]=1 //没有定义数组之前也可这样直接定义元素
[root@localhost ~]#
[root@localhost ~]# echo ${
list[*]}
1
[root@localhost ~]# list=([0]=1 [1]=2 [3]=4) //定义数组时所以可以是不连续的
[root@localhost ~]# echo ${
list[*]}
1 2 4
[root@localhost ~]# echo ${
!list[*]} //没有2这个索引,数组元素为3
0 1 3
[root@localhost ~]# ff=(1 2 zhangsan lisi) //不是同一数据类型的也可定义为一个数组
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# echo ${
ff[*]}
1 2 zhangsan lisi
2.4数组格式
如:arr=(11 22 33 44)
数组名称:arr
数组元素:11,12,12,14,数组元素默认是以空格分隔的
数组长度:4,有4个元素
数组下标:每个数组元素都有一个下标索引,一般从0开始,33是数组第三个元素,但是它的下标索引是2
2.4.1 数组的常用操作 以及 经典案例
2.4.1.1 读取数组和元素
[root@localhost ~]# fruit=(apple banana orange) //定义了一个水果的数组
[root@localhost ~]# echo ${
#fruit[*]} //查看这个数组元素的个数,也是数组长度
3
[root@localhost ~]# echo ${
!fruit[*]} //查看这个数组元素的索引
0 1 2
[root@localhost ~]# echo ${
fruit[*]} //查看这个数组的元素
apple banana orange
[root@localhost ~]# echo ${
fruit[@]} //查看这个数组的元素
apple banana orange
[root@localhost ~]# echo ${
fruit[0]} //查看这个数组索引为0的元素
apple
[root@localhost ~]# declare -a | grep fruit //查看声明的所有变量可以看到数组
declare -a fruit='([0]="apple" [1]="banana" [2]="orange")'
2.4.1.2 元素切片
[root@localhost ~]# arr=(1 2 3 4 5 6 7 8)
[root@localhost ~]# echo ${
arr[*]:2:3} //提取从索引2开始的3个元素
3 4 5
[root@localhost ~]# echo ${
arr[*]:2:2} //提取从2开始的2个元素
3 4
[root@localhost ~]# echo ${
arr[*]:0:2}
1 2
2.4.1.3 数组的遍历
#!/bin/bash
a=(1 2 3 4 5 6)
for i in ${
a[@]}
do
echo $i
done
2.4.1.4 定义某一个元素
[root@localhost ~]# fruit[0]=pear
[root@localhost ~]#
[root@localhost ~]# echo ${
fruit[*]}
pear banana orange
2.4.1.5元素替换
定义或替换某一个元素
[root@localhost ~]# fruit[0]=pear
[root@localhost ~]#
[root@localhost ~]# echo ${
fruit[*]}
pear banana orange
[root@localhost ~]# echo ${
fruit[*]/banana/ba} //临时替换
pear ba orange
[root@localhost ~]# echo ${
fruit[*]}
pear banana orange
2.4.1.6 元素删除
[root@localhost ~]# unset fruit[0]
[root@localhost ~]#
[root@localhost ~]# declare -a | grep fruit
declare -a fruit=‘([1]=“banana” [2]=“orange”)’
2.4.1.7 数组删除和指定下标的值删除
[root@localhost ~]# unset arr
2.4.1.8 数组追加元素
法一 :直接使用下标进行元素的追加
数组名[下标]=变量
[root@localhost ~]# a=(10 20 30 40)
[root@localhost ~]# echo ${
a[*]}
10 20 30 40
[root@localhost ~]# a[4]=50
[root@localhost ~]# echo ${
a[*]}
10 20 30 40 50
[root@localhost ~]# a[5]=60
[root@localhost ~]# echo ${
a[*]}
10 20 30 40 50 60
法二:将数组的长度作为下标进行追加元素
数组名[${
数组名[@]}]=变量名
法三:使用+=进行追加
数组名+=(变量1 变量2 ...)
2.4.1.9 查看所有数组—declare -a
2.5 获取数组下标对应的值:
数组名=(元素0 元素1 元素2 ……) 定义数组
echo ${
数组名[索引值]} 输出数组索引值对应的元素,索引值为从0开始
2.6 冒泡排序
每次对比,确定最后一位【所以我数组长度需要-1】
#!/bin/bash
array=(90 70 82 100 30 66) #定义数组
echo "old_array:${array[*]}" #1.代表排序前的数组
lt=${
#array[*]} #数组长度
#定义比较轮数,比较轮数为数组长度-1,从1开始
for ((i=1;i<=$lt;i++))
#当下标为0时for ((i=0;i<$lt;i++))
do
#确定比较元素的位置,比较相邻的两个元素,较大的数往后放,在比较次数谁比较轮数而减少
for ((j=0;j<$lt-i;j++))
do
#定义第一个元素的值
first=${
array[$j]}
#定义第二个元素的值
k=$[$j+1]
second=${
array[$k]}
#如果第一个元素比第二个元素大,就互换
if [ $first -gt $second ];then
#把第一个元素的值保存到临时变量中
temp=$first
#把第二个元素赋值给第一个元素
array[$j]=$second
#把临时变量赋值给第二个元素
array[$k]=$temp
fi
done
done
echo "new_array:${array[*]}"
喜欢小编记得点个小星星哦!