目录
一:shell函数定义
1.函数的含义
2.函数的优点
3.函数的格式
4.函数返回值
(1)return输出
(2)echo输出
二:函数传参
1.情景一
2.情景二
3.情景三
4.情景四
三:递归函数
1.递归函数定义
2.通过递归函数实现阶乘
3.使用递归函数实现目录和文件的依次输出
4.案例实练1
5.案例实练2
四:函数库
1.函数库含义
2.函数库实例
一:shell函数定义
1.函数的含义
在shell中,函数是一段代码块,可以在需要时调用。函数通常用于封装重复使用的代码,使代码更简洁、可读性更强。
2.函数的优点
使用函数可以避免代码重复,可以将大的工程分割为若干小的功能模块,使大妈的可读性更强。
3.函数的格式
格式1:
function 函数名 {
命令序列
【return x】 //使用return或exit可以显示地结束函数
}
函数名
格式2:
函数名 () {
命令序列
}
函数名
4.函数返回值
(1)return输出
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值。
使用原则:
1.1函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
1.2退出状态码必须是0-255,超出时值将为除以256取余
[root@localhost hansu]# vim test1.sh
#!/bin/bash
function test01 {
read -p "请输入一个整数:" num
return $[num *2]
}
test01
echo $?
(2)echo输出
echo输出不会有0-255的限制
[root@localhost hansu]# vim test2.sh
#!/bin/bash
sum() {
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$[num1+num2]
echo "两个数的和为:$SUM"
}
sum
二:函数传参
1.情景一
[root@localhost hansu]# vim test3.sh
#!/bin/bash
sum() {
num=$[ $1 - $2 ]
echo $num
}
#$1和$2为脚本后的位置参数
sum $1 $2
2.情景二
[root@localhost hansu]# vim test3.sh
#!/bin/bash
sum() {
num=$[ $1 - $2 ] #参数体内的$1和$2为函数后的位置参数
echo $num
}
sum $2 $1 #$1和$2为脚本后的位置参数
注: 此时参数体外的$2为脚本后跟的位置参数 45 ,参数体内的$1为参数体外跟的的位置参数$2,num=$[ $1 - $2 ] 意思为45 -92。
注: 此时参数体外的$1为脚本后跟的位置参数 92 ,参数体内的$2为参数体外跟的的位置参数$1。
3.情景三
[root@localhost hansu]# vim test4.sh
#!/bin/bash
#定义函数
sum2() {
#函数体内部的$1 $2 代表的是调用函数时,函数后面跟的位置参数
sum=$[$1 - $2]
echo $sum
echo "在函数体内部的\$#代表调用函数时,函数后面跟的参数个数,当前函数后面有$#个参数"
echo "在函数体内部的\$@代表调用函数时,函数后面跟的所有参数,当前函数后面的参数有:$@"
echo "在函数体内部,\$0代表$0,为脚本本身"
}
echo "在函数体外时,\$#代表脚本后面跟的参数个数,当前脚本后面有$#个参数"
echo "在函数体外时,\$@代表脚本后面跟的所有参数,当前脚本后面参数有:$@"
echo "在函数体外,\$0代表$0,为脚本本身"
#调用函数
#函数体外的$1 $2 代表的是执行脚本时,脚本后面跟的位置参数
sum2 $2 $1
4.情景四
函数变量的作用范围:
函数在shell脚本中仅在当前shell环境中有效,shell脚本中变量默认全局有效,将变量限制在函数内部使用local命令。
[root@localhost hansu]# vim test5.sh
#!/bin/bash
A01() {
echo $name
#local 将变量限制在函数体内
local name=laoliu
echo $name
}
name=laowang
A01
echo $name
三:递归函数
1.递归函数定义
函数调用自己本身的函数
2.通过递归函数实现阶乘
[root@localhost hansu]# vim test6.sh
#!/bin/bash
fact() {
if [ $1 -eq 1 ];then #当第一个位置参数等于1,就输出1
echo 1
elif [ $1 -gt 1 ];then #当位置参数大于1时
local tmp=$[$1 - 1] #函数体内变量tmp为位置参数减一
local res=$(fact $tmp) #重新调用函数
echo $[$1 * res] #输出位置参数$1乘以函数体内变量res
else
echo "输入的值无效。请输入大于等于1的整数!"
fi
}
#####main#####
read -p "请输入一个大于等于1的整数:" num
res=$(fact $num) #将结果赋予新变量
echo "$num的阶乘值为$res"
3.使用递归函数实现目录和文件的依次输出
使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录则输出目录名且输出此目录下的所有目录和文件名
[root@localhost hansu]# vim test7.sh
#!/bin/bash
listf () {
for f in $(ls $1) #f在查看/var/log的环境中
do
if [ -d "$1/$f" ];then #判断/var/log/下$f是否为目录
echo "$2目录$f" #是目录输出目录
listf "$1/$f" " $2" #重新调用函数,继续递归查看判断并缩进两个字符
else
echo "$2文件$f" #其他,即输出为文件
fi
done
}
#/var/log为函数后跟的$1位置参数,空为$2位置参数
listf "/var/log" ""
4.案例实练1
执行命令 mkdir -p /root/bin/aa/bb/cc/dd ; touch /root/bin/aa/bb/cc/dd/abc.txt,
通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件
[root@localhost hansu]# vim test8.sh
#!/bin/bash
#定义一个遍历PATH环境变量的函数
list_path() {
IFSB=$IFS #备份IFS
IFS=$IFS':' #重新赋值,允许以:分割
for F in $PATH #设置for循环
do
echo $F
done
IFS=$IFSB #还原IFS
}
#定义一个递归函数
listf() {
for F in $(ls $1)
do
if [ -d "$1/$F" ];then #如果PATH下的$F为目录
echo "$2$F" #输出目录名,$2为空
listf "$1/$F" " $2" #重新调用函数,递归查询判断,并缩进两个字符
else
if [ ! -x "$1/$F" ];then #如果没有执行权限
echo "$2$F" #输出文件名
fi
fi
done
}
######main######
folder=$(list_path) #folder获取目录
for path in $folder #遍历目录
do
echo $path
listf "$path" " " #调用递归函数
done
5.案例实练2
将一个点分十进制格式的IP地址转换成点分二进制格式
比如 255.255.255.255 --> 11111111.11111111.11111111.11111111
[root@localhost hansu]# vim test9.sh
#!/bin/bash
#!/bin/bash
#定义一个用于十进制转换为二进制的函数
switch_bin() {
NUM=$1 #位置变量进行传参
for i in {1..8} #循环8次
do
SUM=$[NUM % 2]$SUM #取余
let NUM/=2 #除以2
done
echo $SUM
}
#定义一个用于分割IP的函数
SPT() {
IP=$1 #获取$1的变量
for i in {1..4} #循环4次
do
num=${IP%%.*} #从后面开始删除
IP=${IP#*.} #从前面开始往后删除
BIN=$(switch_bin num) #转换
echo -n $BIN.
done
}
#####main#####
read -p "请输入一个合法IP:" INIP #输入ip地址
res=$(SPT $INIP) #转换后的结果
echo ${res%.*} #删掉最后一个点
四:函数库
1.函数库含义
在shell中,可以将一些常用的函数封装成函数库,方便在多个脚本中复用。函数库一般以.sh为后缀,可以在脚本中通过source命令引入。
2.函数库实例
(1)编辑函数库
[root@localhost hansu]# vim hsk
jiafa() { #定义加法函数
echo $[$1 + $2]
}
jianfa() { #定义减法函数
#!/bin/bash
jiafa() { #定义加法函数
echo $[$1 + $2]
}
jianfa() { #定义减法函数
echo $[$1 -$2]
}
chengfa() { #定义乘法函数
echo $[$1 * $2]
}
chufa() { #定义除法函数
if [ $2 -eq 0 ];then
echo "除数不可为0"
else
echo $[$1 / $2]
fi
}
fact() { #定义阶乘函数
if [ $1 -eq 1 ];then
echo 1
elif [ $1 -gt 1 ];then
local tmp=$[$1 - 1]
local res=$(fact $tmp)
echo $[$1 * res]
else
echo "输入的值无效。请输入大于等于1的整数!"
fi
}
(2)编辑函数脚本,运行
[root@localhost hansu]# vim test10.sh
#!/bin/bash
#加载函数库文件到当前脚本的shell
. /opt/hansu/hsk
#定义两个变量
value1=15
value2=6
res1=$(jiafa $value1 $value2)
res2=$(jianfa $value1 $value2)
res3=$(chengfa $value1 $value2)
res4=$(chufa $value1 $value2)
res5=$(fact $value1 $value2)
echo "加法的结果为$res1"
echo "减法的结果为$res2"
echo "乘法的结果为$res3"
echo "除法的结果为$res4"
echo "阶乘的结果为$res5"