shell 函数,递归函数,创建函数库
一: shell 函数的概述
1.1 什么是函数
1.2 函数的定义方法
1.3 函数的返回值
1.4 函数的传参
1.5 函数变量的作用范围
二:递归函数
2.1 阶乘
2.2 递归目录
三,创建函数库
3.1 编写函数库
3.2 调用函数库
一: shell 函数的概述
1.1 什么是函数
-
将命令序列按格式写在一起,可方便重复使用命令序列
1.2 函数的定义方法
方法一:
function 函数名 {
命令序列
}
方法二:
函数名 () {
命令序列
}
1.3 函数的返回值
return表示退出函数并返回一个退出值,脚本中可以用 $ ? 变量显示该值
使用原则:
-
1、函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
-
2、退出状态码必须是0~255,超出时值将为除以256取余
#!/bin/bash
#定义一个函数
function db1 {
read -p "请输入:" value #将用户的输入作为变量value 的值
return $[$value *2 ] #将value的值乘 2 作为函数的返回值
}
############ main #######
#调用函数
db1
#输出函数的的返回值
echo $?
1.4 函数的传参
#!/bin/bash #定义一个函数 sum1 () { sum=$[$1+$2] # $1 与 $2 为 函数的位置变量,而不是脚本的位置变量 echo $sum } ############ manin ######## read -p "请输入第一个值:" first read -p "请输入第二个值:" second #调用函数,并将变量 first 和 second 函数的位置变量,传递给函数 res=$(sum1 $first $second) #将函数的执行结果赋值给变量res #输出变量 res 的值 echo $res
#!/bin/bash
#定义函数
sum2() {
sum=$[$1+$2]
echo $sum
}
############### main #############
#这里的 $1,$2 和函数里的位置变量$1,$2不同,这里的代表的是脚本的位置变量
#将脚本的位置变量$1 赋值给变量 first
first=$1
#将脚本的位置变量$2 赋值给变量 second
second=$2
#调用函数,并将变量 $first , $second 的值分别作为函数的位置变量$1,$2传递给函数
res=$(sum2 $first $second)
echo $res
1.5 函数变量的作用范围
-
函数在Shell脚本中仅在当前Shell环境中有效 (使用路径执行,和使用source 执行,结果不同)
-
Shell脚本中变量默认全局有效
-
将变量限定在函数内部使用local命令
function () {
local i # 定义一个局部变量i
i=8 # 为局部变量 i 赋值
}
function () {
local i=8 # 直接定义局部变量i的值为8
}
#!/bin/bash
myfunc(){
#定义全局变量 i 的值为10
i=10
local i=8 #定义局部变量i 的值为 8
echo $i #输出变量 i 的值
}
######### main ####
i=9 #定义变量i的值为9
myfunc #调用函数
#输出变量i的值
echo $i
-
脚本执行时从主程序代码开始从上往下执行。先执行命令"i=9" ,定义一个全局变量 i ,它的值为9
-
然后执行"myfunc",这是调用函数。接着,从上往下执行函数里的命令。
-
函数里先执行 “i = 10 ” 命令,定义一个全局变量 i ,它的值为10。此时,全局变量 i 的原值 9 被 现在的值 10 覆盖。也就是说, 现在,全局变量i 的值为 10
-
然后在执行函数里的“ local i=8” 命令,定义一个局部变量 i ,值为8。
-
在执行函数里 "echo $i" 命令,因为是在 "local i =8" 命令下面,所以会输出局部变量 i 的值,
-
函数执行完毕,再执行主程序里的命令 “echo $i " 因为,局部变量仅在函数内有效,所以输出的是全局变量 i 的值
二:递归函数
2.1 阶乘
#!/bin/bash
fact(){
#将函数的位置变量$1赋值给变量nun
num=$1
#判断变量 num 值是否为1 ,1的阶乘结果为1
if [ $num -eq 1 ]
then
echo 1
else
#让局部变量temp 的值,每次递归减1
local temp=$[$num - 1]
#变量result重复调用函数,函数的位置变量为变量temp的值。
#直到变量result的值为1,结束函数调用
local result=$(fact $temp)
#可以看成 5*$result(4*$result(3*$result(2*$result(1))))
#输出结果
echo $[$num * $result]
fi
}
############# main #######
read -p "请输入阶乘的数值:" n
result=$(fact $n)
echo "$n 的阶乘结果为: $result"
2.2 递归目录
mkdir -p /root/bin/aa/bb/cc/dd; touch /root/bin/aa/bb/cc/dd/abc.txt
输出$PATH 包含的所有目录,以及其中的子目录和所有的不可执行文件
#!/bin/bash
function list_files {
#for 循环遍历,也可以for i in $1/*
for f in $(ls $1)
do
#补全路径,并判断是否为目录
#for 循环遍历得到的只是目录下的相对目录,所以要加上$1补全绝对路径
if [ -d "$1/$f" ]
then
echo "$2$f" #开始$2是空,所以$f(目录)会顶格显示
#自己调用自己,调用函数list_files,并将"$1/$f" “----$2" 分别作为函数的位置变量$1,$2
list_files "$1/$f" "----$2"
else
if [ ! -x "$1/$f" ];then #没有执行权限为真
echo "不可执行的文件有:$2$f"
fi
fi
done
}
########################### main ##############
#linux 里的分隔符保存在 变量 IFS 中,默认是空格,制表符,换行符。先将IFS 的值存储到 变量 OLDIFS 中
OLDIFS=$IFS
#将变量 IFS 的值,加上 ’:'
IFS=$IFS':'
#遍历 $PATH 的值
for folder in $PATH
do
#输出变量$PATH 的值
echo $folder
# 调用函数。函数的第一个位置变量$1为 $folder 的值(folder 的值是遍历 变量$PATH 取来的)
#函数的第二个位置变量$2 的值为空 ""
list_files "$folder" ""
done
#变量IFS 取回原来的值
IFS=$OLDIFS
三,创建函数库
把常用的函数放入一个单独的库脚本中,方便脚本在使用时,可直接调用这个库中的函数
3.1 编写函数库
#!/bin/bash
#编写函数库文件
#定义阶乘函数
fact(){
if [ $1 -eq 1 ];then
echo 1
else
local temp=$[ $1 - 1 ]
local result=$(fact $temp)
echo $[ $1 * $result ]
fi
}
#定义加法函数
jiafa() {
echo $[ $1 + $2 ]
}
#定义减法函数
jianfa() {
echo $[ $1 - $2 ]
}
#定义乘法函数
chengfa(){
echo $[ $1 * $2 ]
}
3.2 调用函数库
#进行函数库调用,写上函数库的路径。
. dem6.sh
v1=$1
v2=$2
#调用函数库函数
res1=$(jiafa $v1 $v2)
res2=$(jianfa $v1 $v2)
res3=$(chengfa $v1 $v2)
res4=$(chufa $v1 $v2)
res5=$(fact $v1)
echo "加法的结果为 $res1"
echo "减法的结果为 $res2"
echo "乘法的结果为 $res3"
echo "除法的结果为 $res4"
echo "$1阶乘的结果为 $res5"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现