shell脚本--函数

news2024/12/27 12:12:38

目录

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

   

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32F103ZET6驱动TOF250激光测距传感器

STM32驱动TOF250激光测距传感器 TOF250介绍I2C通讯协议I2C寄存器地址 TOF250引脚说明和STM32的接线和STM32的接线 程序实验结果总结 TOF250介绍 TOF250是一款基于TOF原理的单点测距雷达,采用940nm红外光源,提供了精确和可重复的远 距离测量用于高速自动对…

OceanBase写入限速源码解读

一、简介 OceanBase中的写入限速机制旨在控制系统中写入操作(一般写入操作包括插入、更新和删除等)的速率,目的是为了提高数据库系统的稳定性。本文主要通过以下2个参数来解释写入限速的实现机制。 **1.**writing_throttling_trigger_perce…

MySQL-----索引特性

文章目录 前言一、没有索引,可能会有什么问题二、认识磁盘MySQL与存储先来研究一下磁盘在看看磁盘中一个盘片扇区结论磁盘随机访问(Random Access)和连续访问(Sequential Access) 三、MySQL与磁盘交互的基本单位四、建立共识五、索引的理解建立测试表插入多条记录查看插入结果中…

程序员最终会被自己开发的轮子所淘汰吗?

螺丝刀和扳手的发明,并没有让工人下岗; 工程机械(挖掘机等)的发明,也不会让建筑工人的需求量减少; 现代医学的各种先进设备,似乎也没有让医生数量大幅减少; …… 所以,关…

【团购-自定义Cell完善 Objective-C语言】

一、我们刚才这么写,有一个问题, 1.CZGoodsCell *cell = [[NSBundle mainBundle] loadNibNamed:@“CZGoodsCell” owner : nil options : nil ] ; 这样是不是没有进行单元格重用啊, 没有重用单元格, 我们说,前面还有一个对单元格进行重用吧, static NSString *ID = @“…

4.shell函数

文章目录 shell函数shell函数的作用函数返回值函数传参函数变量作用范围递归阶乘使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录则输出目录名且输出此目录下的所有目录和文件名通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录…

python的小技巧

python的小方法 (1)利用dir()这个函数方法,知道库里面的方法有些什么。(2) 利用type()这个函数方法,知道是什么类型的数据(3)从序列元素中获取元素[1]单个星号还可以在列表/元组/字典…

纯干货!蓝牙耳机哪个牌子好?性价比高蓝牙耳机推荐

蓝牙耳机是我们使用最多的数码产品之一,不论是通勤、运动、上课都少不了它。身为数码测评专员,我每天都会进行测评,对各类数码产品也有深入研究,近期很多网友咨询蓝牙耳机哪个牌子好,于是我进行深入测评后整理了这份性…

【刷题】141. 环形链表

141. 环形链表 一、题目描述二、示例三、实现思考总结 141. 环形链表 一、题目描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环…

基于jdk11从源码角度剖析AQS 抽象同步其的核心原理

在高并发的情况下,使用基于CAS自旋实现的轻量级锁存在恶性空自旋浪费CPU 资源和导致“总线风暴”两大问题, 解决CAS恶性空自旋的有效方法是空间换时间,常见解决方法有分散操作热点和使用队列削峰。JUC并发包使用的是队列削峰的方案解决CAS的性…

YOLOv7升级换代:EfficientNet骨干网络助力更精准目标检测

目录 一、EfficientNet骨干网络1、EfficientNet架构2、EfficientNet在目标检测中的应用3、EfficientNet分辨率的缩放4、EfficientNet深度与宽度的缩放 二、YOLOv7结构1、YOLOv7网络架构2、YOLOv7骨干网络3、YOLOv7使用了EfficientNet作为骨干网络,具有以下几个优点&…

如何基于异步消息队列进行深度学习模型推理预测?distributed inference with pytorch celery huey sqlite

文章目录 celery 简介celery in pytorchwindows 平台下使用celery 的一些问题参考文献与学习路径一些类似消息队列多进行推理预测的实现参考celery and sqlitecelery vs hueycelery 简介 先说一下celery 不支持windows 【或者说支持的不好】 pypi https://pypi.org/project/…

docker-安装prometheus

概述 什么是Prometheus 如果对Prometheus不熟悉的, 可以先了解一下Prometheus的官网或者文档; Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在kubernetes容器管理系统中&…

基于java和go-cqhttp实现QQ机器人

目录 yh-qqrobot机器人简介go-cqhttp搭建1.下载应用2.生成bat文件3. 初始化项目4. 配置5. 运行项目 yh-qqrobot搭建搭建后端1. 导入sql文件2. 配置文件3. 导入到idea 搭建前端 yh-qqrobot机器人简介 yh-qqrobot是一个基于若依框和go-cqhttp集成的系统,一开始我只是揣…

ACM 1010 | 利润计算

文章目录 0x00 前言 0x01 题目描述 0x02 问题分析 0x03 代码设计 0x04 完整代码 0x05 运行效果 0x06 总结 0x00 前言 C 语言网不仅提供 C 语言,还包括 C 、 java 、算法与数据结构等课程在内的各种入门教程、视频录像、编程经验、编译器教程及软件下载、题解博…

day2_内存区域2垃圾回收算法

文章目录 方法区1.StringTable2.StringTable的位置3.StringTable的调优 垃圾回收1. 判断垃圾2. 5种引用3. 垃圾回收算法 方法区 前面提到了方法区中的组成,它的组成主要是: class(例如它的属性,方法等)常量池(StringTable等)类加载器 在jdk 1.8中&…

【python学习】基础篇-文件与系统-文件信息获取与目录操作

python内置文件高级操作函数 删除文件 Python 没有内置删除文件的函数,但是在内置的 os 模块中提供了删除文件的 remove()函数,语法格式如下: os.remove(path) 其中,path 为要删除的文件路径,可以使用相对路径,也可以…

P1058 [NOIP2008 普及组] 立体图

题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们讲些自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。 小渊有一块面积为 ��mn 的矩形区域,上面有 �&#x…

number类型超出16位的问题(前端、后端处理)

目录 1、前端解决方案 1.1 甩链接 1.2 接口返回数据过程中将数据处理为字符串(过过嘴瘾) 1.3 对返回的json字符串进行数据预处理代码如下 2、后端解决方案 2.1 toString、String、 、new String() 自己悟、就是要改的地方多。 2.2拦截器 (可能超出…

为什么越来越多的企业选择云计算?

一、前言 1.当下企业信息化的痛点 企业信息化,这也算是一个老生常谈的话题了,整个中国业内前前后后应该喊了有十多年了。不过到目前为止,我国很多企业公司都还没真正形成一个完整的信息化框架,或者只是运用了一个简单财务或客户…