目录
概述
- Shell函数是将命令序列按格式写在一起,并且可以方便重复的使用命令序列
- 也可理解为函数其实就是一串命令的别名
定义Shell函数的方式
[root@localhost ~]# ./16.sh
3
5
7
9
11
[root@localhost ~]# vim 16.sh#!/bin/bash
#function q1 { 【定义函数方式一】
#w=$[$1 + $2]
#echo $w
#}q1() { 【定义函数方式二】
w=$[$1 + $2]
echo $w
} 【定义函数q1执行“变量w等于参数1+参数2的值”并输出】for ((q=1;q<=5;q++))
{q1 $q $q+1
} 【将第一个参数q和第二个参数q+1的值输入到函数q1里进行相关命令的执行】
函数返回值
- return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值
- 使用原则
- 1.函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
- 2.退出状态码必须是0-255,当状态码超出255时则除以256并取余
返回函数值的方法一
[root@localhost ~]# ./17.sh
请输入数值: 500
232 【因为输入500,返回值为500*2,超255,所以除256取余】
[root@localhost ~]# vim 17.sh#!/bin/bash
mfj() {
read -p "请输入数值: " z
return $[$z * 2]}
mfj
echo $?
返回函数值的方法二
- 不受返回值255上限
[root@localhost ~]# ./18.sh
请输入:500
1000
[root@localhost ~]# vim 18.sh#!/bin/bash
mfj(){
read -p "请输入:" z
echo $[$z * 2 ]
}
mfj1=`mfj` 【用反撇号提取函数qz1输出的值并赋给变量mfj1】
echo $mfj1 【输出变量mfj1的值】
函数中的传参方式
[root@localhost ~]# ./19.sh
输入第一个参数值:3
输入第二个参数值:9
12
[root@localhost ~]# vim 19.sh#!/bin/bash
mfj() {
z=$[$1 + $2]
echo $z}
read -p "输入第一个参数值:" one
read -p "输入第二个参数值:" two
mfj $one $two
通过传参自定义计算(10000-100000)*2的值求
[root@localhost ~]# ./20.sh 10000 100000
9900110000
[root@localhost ~]# vim 20.sh#!/bin/bash
mfj() {
mfj2=0
for (z=$1; z<=$2; z++))
do
mfj2=$[$mfj2 + $z*2] 【计算公式,并将值赋给mfj2】done
echo $mfj2}
mfj1=`mfj` $1 $2`
【这里的参数1和参数2是命令行的位置参数,并将获得到的位置参数输入到函数内进行命令操作。并通过反撇号获取“当函数mfj的参数1和参数2分别是命令行输入的参数结果时的值”】
echo $mfj1
【最终通过echo输出变量mfj1获取到的值】
函数变量的作用范围
- 函数在Shell脚本仅在当前Shell环境中有效
- Shell脚本中变量默认全局有效
- 将变量限定在函数内部可使用local命令
[root@localhost ~]# ./21.sh
9
11
13
2
5
8
2
6
[root@localhost ~]# vim 21.sh#!/bin/bash
mfj() { 【函数名为mfj】
echo $z 【输出新变量z的值=11】
z=$[$z+2] 【再次定义新z的值为上一个z的值+2】
echo $z 【输出重新定义的变量z值,也就是13】
z=2 【再次定义变量z=2】
echo $z 【输出刚定义的变量z,也就是2】
z=6 【再次定义变量z的新值为6,但函数内没有echo进行输出操作】
local z 【将变量z限定在函数内部可使用】
z=4 【定义变量z=4】
z=$[$z+1] 【定义新的变量z是上一个z+1的值】
echo $z 【输出新变量z的值,也就是5】
z=8 【再次定义变量z值为8】
echo $z 【输出刚定义的变量z值为8】
}z=9
echo $z 【输出变量z=9的值】
z=$[$z+2] 【重新定义变量z值等于之前z值+2,也就是11】
mfj 【运行函数】echo $z 【输出函数内定义的z=6值】
递归
- 递归即函数调用自己本身函数的操作
递归阶乘
- 一个正整数的阶乘是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!
- 即n!=1×2×3×…×(n-1)×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n
[root@localhost ~]# ./23.sh
输入你想要阶乘的数值:10
3628800
[root@localhost ~]# ./23.sh
输入你想要阶乘的数值:20
2432902008176640000
[root@localhost ~]# vim 23.sh#!/bin/bash
qz() { 【函数名为mfj】
if [ $1 -ne 1 ];then 【进行位置参数1(输入的想要阶乘数值num)不等于1的判断】
local mfj1=$[$1-1] 【定义变量mfj1=位置参数1的值-1,并用local进行限定,使其只在函数内部可使用】
local mfj2=`mfj $mfj1` 【定义变量mfj2=函数mfj里的变量mfj1命令运行后的结果,并用反撇号进行提取,用local进行限定。
因为每次都需要获得位置参数1减1的值,所以不能直接mfj2=mfj1,需要定义为mfj函数内的mfj1值】
echo $[$1*$mfj2] 【输出值为位置参数1*变量mfj2的值】else
echo 1
fi
}read -p "输入你想要阶乘的数值:" num
mfj $num 【将变量num传参到函数mfj内】
递归目录
方式一
- 用通配符*时则当没有文件或者目录时用*表示
[root@localhost ~]# ./24.sh
输入你想要查询的目录名:/var/log
/var/log/anaconda:
...略...
...略...
/var/log/secure-20230714
/var/log/speech-dispatcher:
/var/log/speech-dispatcher/ * 【前面2个空格以突显层级关系,通配符*代表该目录中无文件】
/var/log/tallylog
...略...
/var/log/yum.log[root@localhost ~]# vim 24.sh
#!/bin/bash
mfj() {
for z in $1/ * 【用for循环输出参数1,通配符*代表输入的参数下所有的文件和子目录,并赋值给变量z】
do
if [ -d $z ];then 【用-d判断变量z是否为目录,因为变量z是输入的绝对路径】
echo "$2$z: " 【如果条件成立则输出变量z的值,这里的$2在第一次循环时是无值,则没有空格】
mfj $z " $2" 【调用mfj函数本身,当第二次递归操作时则有1个空格,第三次递归操作则有2个空格,以表示层级关系】
else
echo "$2$z" 【如果条件不成立,则输出第N此递归得到的空格及z的值】
fi
done
}read -p "输入你想要查询的目录名:" dir
mfj $dir "" 【将输入的值进行传参到mfj函数内,第二个位置参数""用来缩进以区分子目录】
方式二
- 用ls的方式则当没有文件或者目录时无任何显示
[root@localhost ~]# vim 24.sh
[root@localhost ~]# ./24.sh
输入你想要查询的目录名:/var/log
...略...
...略...
tuned:
tuned.log
vmware-vgauthsvc.log.0
[root@localhost ~]# vim 24.sh#!/bin/bash
mfj() {
for z in $(ls $1)
do
if [ -d $1/$z ];then
echo "$2$z: "
mfj $1/$z " $2"
else
echo "$2$z"
fidone
}
read -p "输入你想要查询的目录名:" dir
mfj $dir ""
函数库
- 将经常使用的重复代码封装成函数库文件
- 函数库一般不直接执行,而是由其他脚本调用
[root@localhost ~]# ./25.sh 132 2
加法的结果为:134
减法的结果为:130
乘法的结果为:264
除法的结果为:66
[root@localhost ~]# ./25.sh 132 0
加法的结果为:132
减法的结果为:132
乘法的结果为:0
除法的结果为:除数不能为0!
[root@localhost ~]# vim mykun.sh 【定义函数库里的相关操作】
#!/bin/bash
echo $[$1 + $2]
}jianfa() {
echo $[$1 - $2]
}chengfa() {
echo $[$1 * $2]
}chufa() {
if [ $2 -ne 0 ];then
echo $[$1 / $2]
else
echo "除数不能为0!"
fi
}[root@localhost ~]# vim 25.sh 【定义函数】
. /root/mykun.sh 【.或者source+脚本路径,因为函数库里定义了/bin/bash,所以这里的调用则不需要再次定义】
a=$1 【代表命令行里的第一个位置参数】
b=$2 【代表命令行里的第二个位置参数】
mfj1=`jiafa $a $b`
【变量mfj1=通过命令行位置参数获取的变量a和变量b的值传参到函数库的jiafa函数里,并通过反撇号提取jiafa函数获得传参后的运行结果】
mfj2=`jianfa $a $b`
mfj3=`chengfa $a $b`
mfj4=`chufa $a $b`echo "加法的结果为:$mfj1"
echo "减法的结果为:$mfj2"
echo "乘法的结果为:$mfj3"
echo "除法的结果为:$mfj4"