shell 函数,递归函数,创建函数库

shell 函数,递归函数,创建函数库

 

 

一: 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 $?

image-20210729230745029

 

 

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

image-20210729231501651

 

 

 #!/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
 

image-20210729232138405

 

 

 

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

 

image-20210729233127985

  1. 脚本执行时从主程序代码开始从上往下执行。先执行命令"i=9" ,定义一个全局变量 i ,它的值为9

  2. 然后执行"myfunc",这是调用函数。接着,从上往下执行函数里的命令。

  3. 函数里先执行 “i = 10 ” 命令,定义一个全局变量 i ,它的值为10。此时,全局变量 i 的原值 9 被 现在的值 10 覆盖。也就是说, 现在,全局变量i 的值为 10

  4. 然后在执行函数里的“ local i=8” 命令,定义一个局部变量 i ,值为8。

  5. 在执行函数里 "echo $i" 命令,因为是在 "local i =8" 命令下面,所以会输出局部变量 i 的值,

  6. 函数执行完毕,再执行主程序里的命令 “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"

image-20210730000509892

 

 

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

image-20210730002157032

 

 

 

三,创建函数库

把常用的函数放入一个单独的库脚本中,方便脚本在使用时,可直接调用这个库中的函数

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"
 

image-20210730004758747

 

 

posted @ 2021-08-04 14:24  知己一语  阅读(222)  评论(0编辑  收藏  举报