shell脚本--函数

目录

一: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"

   

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/19006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ASEMI代理ADUM3223ARZ-RL7原装ADI车规级ADUM3223ARZ-RL7

编辑:ll ASEMI代理ADUM3223ARZ-RL7原装ADI车规级ADUM3223ARZ-RL7 型号:ADUM3223ARZ-RL7 品牌:ADI /亚德诺 封装:SOIC-16 批号:2023 安装类型:表面贴装型 引脚数量:16 工作温度:-40C~125…

利用MQ事务消息实现分布式事务

MQ事务消息使用场景 消息队列中的“事务”,主要解决的是消息生产者和消息消费者的数据一致性问题。 拿我们熟悉的电商来举个例子。一般来说,用户在电商 APP 上购物时,先把商品加到购物车里,然后几件商品一起下单,最后…

2路 QSFP,40G 光纤的数据实时采集(5GByte/s 带宽)板卡设计原理图 -PCIE732

板卡概述 PCIE732 是一款基于 PCIE 总线架构的高性能数据传输卡,板卡具有 1 个 PCIex8 主机接口、2 个 QSFP40G 光纤接口,可以实现 2 路 QSFP 40G 光纤的数据实时采集、传输。板卡采用 Xilinx 的高性 能 Kintex UltraScale 系列 FPGA 作为实时处理器…

qiankun 微前端 demo(Vue2)

前言 这是我最近刚开始学微前端(qiankun框架)做的一个小demo,做的时候还是遇到很多问题的,在网上也是看了很多别人的Blog,最后也是磨出来了😂😂😂;这篇文章总统分为分为…

windows 编译 opencv

编译需要的基础工具 #cmake是配置构建工具,mingw是编译工具 cmake CMake是一款跨平台的编译管理工具,可以自动生成各种不同编译环境(如Makefile、Visual Studio Solution等),从而实现在不同平台上进行代码编译的目的…

Qwik 1.0 发布,全栈式 Web 框架

Qwik 是一个全栈式 Web 框架,Qwik 基于 React、Angular 和 Vue 等其他 Web 框架的概念,但以 JavaScript 流等更新的方法脱颖而出,允许以高性能向用户交付复杂的 Web 应用程序。 随着 Web 应用程序变得越来越大,它们的启动性能会下…

强烈推荐:一款中文AI问答、创作、绘画工具

前言 相信很多人已经听过ChatGPT这款人工智能机器人了,它能够根据用户输入的内容,自动生成智能回复。它使用自然语言处理技术,通过学习大量的文本资料,能够模拟人类的对话行为。它是由OpenAI开发的,一家非常伟大的人工…

Http知识

一、http协议 目前存在HTTP1.1(当前广泛运用的版本)、HTTP2.0和HTTP3.0协议,有以下的优点和缺点 1. HTTP1.1 优点:默认支持长连接,即在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的…

Flutter框架:从入门到实战,构建跨平台移动应用的全流程解析

第一章:Flutter框架介绍 Flutter框架是由Google推出的一款跨平台移动应用开发框架。相比其他跨平台框架,Flutter具有更高的性能和更好的用户体验。本章将介绍Flutter框架的概念、特点以及与其他跨平台框架的比较,以及Flutter开发环境的搭建和…

应急物流 | 灾后早期阶段多目标选址路径问题的混合元启发式算法

解读作者:李奡,闫同仁 A hybrid meta-heuristic algorithm for the multi-objective location-routing problem in the early post-disaster stage Tongren Yan, Fuqiang Lu, Suxin Wang, Leizhen Wang, Hualing Bi Journal of industrial and managem…

设计原则之【接口隔离原则】,我只做我能做的事

文章目录 一、什么是接口隔离原则二、实例三、总结接口隔离原则与单一职责原则的区别 一、什么是接口隔离原则 接口隔离原则(Interface Segregation Principle, ISP)是指用多个专门的接口,而不使用单一的总接口,客户端不应该依赖…

【中级软件设计师】—(下午题)试题三精讲总结(四十二)

【中级软件设计师】—(下午题)试题三精讲总结(四十二) 一、关系 二、UML中的图 A包含B,那么A执行操作前必须要先执行B 试题一(2021年下半年) 试题2(2021年上半年) 官方…

Docker中部署监控

Docker概念 一、部署Prometheus+grafana环境 1.1 、部署Prometheus+grafana环境 docker pull registry.cn-hangzhou.aliyuncs.com/lhrbest/lhrprometheus:1.0 docker tag registry.cn-hangzhou.aliyuncs.com/lhrbest/lhrprometheus:1.0 lhrbest/lhrprometheus:1.01.2 、创建镜…

linux 定时器

Linux 系统实现底半部的机制主要有tasklet,工作队列和软中断。 tasklet 和工作队列都是调度中断底半部的良好机制,tasklet 基于软中断实现。 内核定时器也依靠软中断实现;内核中的延时是忙等待或者睡眠等待,为了充分利用CPU资源&#xff0c…

docker 搭建 Elasticsearch和Kibana 8.x版本

参考: docker入门:单机elasticsearch安装记录,保证无坑_8月日更_小鲍侃java_InfoQ写作社区 新建文件夹 同上文所述相同,需要在宿主机上挂载配置文件与数据文件。 mkdir -p /Users/louye/data/learn-data/elastic/config mkdir -p /Users/lo…

从地方旅游的宣传谈起:如何吸引主流媒体报道,强势刷屏?

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 五一小长假已经过去好几天了,大家渐渐的从假期舒适的闲暇转到正常的工作生活中了,但利用五一热点宣传的余温还在继续,今天胡老师就i注意到一篇题为&am…

华为nqa实验拓扑案例

nqa是一种实时的网络性能探测和统计技术,可以对响应时间、网络抖动、丢包率等网络信息进行统计。如图1所示,接口备份与NQA联动功能配置相对简单,只需在本端RouterA上配置NQA测试例,并在RouterA的备份接口上配置接口备份与NQA联动&…

重写Properties类,实现对properties文件的有序读写,数据追加,解决中文乱码

前言 *.properties文件,是 Java 支持的一种配置文件类型,并且 Java 提供了 properties 类来读取 properties 文件中的信息。文件中以键值对 "键值"的形式,存储工程中会多次重复使用的配置信息,通过“Properties”类来读…

4.Redis10大数据类型

Redis10大数据类型 Which 101.String(字符串)2.List(列表)3.hash (哈希)4.Set(集合)5.zset(sorted set:有序集合)6.Redis GEO (地理空间)7.HyperL…

Linux最常用的15个基本命令

目录 Linux基本命令 命令1:ls (查看指定目录中有哪些内容) ls / 相当于查看根目录中的内容,相当于查看我的电脑 ls -l(小写l,或者使用ll)详细查看目录下所有内容 ls /usr/lib&#xff08…