当前位置: 首页 > news >正文

Shell脚本函数简介及运用

目录

一、函数的作用

二、定义函数

三、调用函数

1.在脚本中调用函数

2.在函数中调用函数

四、函数传参

五、函数的返回值

六、函数的递归

七、函数及其变量的作用范围

八、外部脚本调用函数


一、函数的作用

  1. 语句块定义成函数约等于别名,定义函数,再引用函数
  2. 封装的可重复利用的具有特定功能的代码

二、定义函数

        定义函数就是只将一段实现某个任务的命令序列封装进一个函数,便于使用和后期维护。

function 函数名() {
    命令序列
}
 
函数名() {
    命令序列
}

[root@localhost1 func]#vim definite.sh
#!/bin/bash
#定义函数运算()
function yunsuan() {
  a=2
  b=3
  jia=$[ $a + $b ]
  jian=$[ $a - $b]
  echo "相加等于:$jia"
  echo "相减等于:$jian"
}

三、调用函数

        定义过的函数需要调用才能执行其中的命令序列。

1.在脚本中调用函数

[root@localhost1 func]#vim definite.sh
#!/bin/bash
function yunsuan() {
  a=2
  b=3
  jia=$[ $a + $b ]
  jian=$[ $a - $b]
  echo "相加等于:$jia"
  echo "相减等于:$jian"
}

#直接在脚本中写入函数名
yunsuan

[root@localhost1 func]#bash definite.sh
相加等于:5
相减等于:-1

2.在函数中调用函数

[root@localhost1 func]#vim definite.sh
#!/bin/bash
function jiajian() {
  a=10
  b=3
  jia=$[ $a + $b ]
  jian=$[ $a - $b]
  echo "相加等于:$jia"
  echo "相减等于:$jian"
}

function chengchu() {
  a=10
  b=3
  cheng=$[ $a * $b ]
  chu=$[ $a / $b]
  echo "相乘等于:$cheng"
  echo "相除等于:$chu"
}

#调用上两个函数
yunsuan() {
  jiajian
  chengchu
}

yunsuan

[root@localhost1 func]#bash definite.sh
相加等于:13
相减等于:7
相乘等于:30
相除等于:3

四、函数传参

        在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值。例如:$1表示第一个参数,$2表示第二个参数…即使用位置参数来实现参数传递。

注意

  • 当我们执行脚本时跟的参数,对应的是脚本中的位置变量
  • 当我们执行函数时跟的参数,对应的是函数中的位置变量

        虽然都表示为$1、$2,但我们执行一个函数时,传入的参数只跟其输入函数的顺序有关,与输入脚本时传入参数的顺序无关。

[root@localhost1 ~]#vim chuancan.sh
#!/bin/bash

test1() {
  jian=$[ $1 - $2 ]   #脚本中的$1对应先传入的30,$2对应后传入的50
  echo "相减的值为:$jian"
}

test1 $2 $1   #执行函数时,先传入30($2),再传入50($1)

[root@localhost1 ~]#bash chuancan.sh 50 30  #执行脚本时传入参数 $1对应50 $2对应30
相减的值为:-20

五、函数的返回值

        return 表示退出函数并返回一个退出值,脚本中可以用$?变量表示该退出值(状态码)

在函数中的使用原则

  • 函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码;
  • 退出状态码必须是0~255,超出时值将为除以256取余。
状态码含义
0执行成功
非0不同程度的错误
2用法不当
126不是可执行的
127命令未找到
[root@localhost1 array]#vim returntest.sh
#!/bin/bash
returntest1() {
  if [ $1 -eq $passwd ];then
    echo "$name的密码输入正确!"
  else
    echo "$name的密码输入错误!"
    return 1
  fi
}

name=张三
passwd=123456
returntest1 $1


[root@localhost1 array]#bash returntest.sh 123
张三的密码输入错误!
[root@localhost1 array]#echo $?  
1     -- 这里输入错误返回了我们指定的状态码1
[root@localhost1 array]#bash returntest.sh 123456
张三的密码输入正确!
[root@localhost1 array]#echo $?
0

六、函数的递归

        是指函数在满足递归条件的情况下,调用函数本身执行到

[root@localhost1 ~]#vim jiecheng.sh
#!/bin/bash
fact() {
  if [ $1 -eq 0 -o $1 -eq 1 ];then
    echo 1
  else
    way=$[$1 - 1]    #迭代方式(指定数每次减1)
    result=$(fact $way)    #递归执行函数(使初始值每次减1)
    echo $[ $1 * $result ]    #输出初始值乘每次递归的值,直到1(实现阶乘效果)
  fi
}
read -p "请输入一个数:" n
result=$(fact $n)
echo "$n的阶乘为:$result"


[root@localhost1 ~]#bash jiecheng.sh
请输入一个数:6
6的阶乘为:720
[root@localhost1 ~]#bash jiecheng.sh
请输入一个数:1
1的阶乘为:1
[root@localhost1 ~]#bash jiecheng.sh 
请输入一个数:4
4的阶乘为:24
[root@localhost1 ~]#bash jiecheng.sh 
请输入一个数:9
9的阶乘为:362880

七、函数及其变量的作用范围

  1. 函数在shell脚本中仅在当前shell环境中有效
  2. shell脚本中变量默认全局有效
  3. 将变量限定在函数内部(定义变量前加上 local 命令)
[root@localhost1 ~]#vim variable.sh
#!/bin/bash
#定义i变量值为1
i=1  

test1() {
 i=10    #定义i变量值为10
 echo $i
}

test1    #调用函数
echo $i    #输出变量i的值

#输出的i均为10,是由于第二点的特性,i的值在函数中被重新赋值了
[root@localhost1 ~]#bash variable.sh
10
10

使用 local 限定函数内部变量

[root@localhost1 ~]#vim variable.sh
#!/bin/bash
i=1

test1() {
 local i=10    #加local限定为内部变量,将不再影响函数外的变量
 echo $i
}

test1
echo $i


[root@localhost1 ~]#bash variable.sh
10
1

八、外部脚本调用函数

        在外部脚本调用一个脚本或文件中的函数,需要先在脚本中加载目标文件,需要使用绝对路径(source 文件名 或 . 文件名),再输入函数名即可执行。

[root@localhost1 ~]#vim hanshu.sh
#!/bin/bash

test1() {
  echo "我是hanshu.sh文件中的test1函数"
}

#在外部脚本中调用hanshu.sh中的test1函数
[root@localhost1 ~]#vim diaoyong.sh
source /root/hanshu.sh

test1

#执行外部脚本
[root@localhost1 ~]#bash diaoyong.sh
我是hanshu.sh文件中的test1函数

调用函数库文件

        函数库文件是指将一些常用的函数提前编写好放入这个函数库文件,当我们编写脚本时,同样通过绝对路径加载函数库文件,在调用其中的函数,这样可以提高代码编写的效率(类似于java中面向对象编程,调用方法)

相关文章:

  • Java并发 | 16.[基础] synchronized简述
  • 一体化伺服电机在新能源汽车充电设备中的应用
  • Java并发 | 15.[基础] 线程安全分析
  • 【web-攻击应用程序框架】(12.1)分层架构:攻击与保障
  • java计算机毕业设计技术交流网站源码+数据库+系统+lw文档+mybatis+运行部署
  • iPhone没有收到iOS16最新版的推送,如何升级系统?
  • 人工神经网络算法的应用,人工神经网络算法步骤
  • 极智Paper | YOLOv7 更高 更快 更强
  • 大型在线考试答题系统源码 B/S架构
  • Uniswap 顶流之路:机制、决策与风险分析
  • Human-level control through deep reinforcement learning
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • 罗氏线圈在有源滤波中的应用
  • JVM学习(宋红康)之运行时数据区之虚拟机栈中栈帧的动态链接及方法调用
  • 基于FPGA的LCD1602驱动(含代码)
  • [译] React v16.8: 含有Hooks的版本
  • 2017届校招提前批面试回顾
  • DOM的那些事
  • in typeof instanceof ===这些运算符有什么作用
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • Js基础知识(四) - js运行原理与机制
  • LeetCode18.四数之和 JavaScript
  • PermissionScope Swift4 兼容问题
  • windows下如何用phpstorm同步测试服务器
  • 基于Android乐音识别(2)
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 赢得Docker挑战最佳实践
  • No resource identifier found for attribute,RxJava之zip操作符
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • (3)STL算法之搜索
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • .Family_物联网
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .net经典笔试题
  • [20180224]expdp query 写法问题.txt
  • [APIO2012] 派遣 dispatching
  • [C++]Leetcode17电话号码的字母组合
  • [DAU-FI Net开源 | Dual Attention UNet+特征融合+Sobel和Canny等算子解决语义分割痛点]
  • [Linux] Ubuntu install Miniconda
  • [OIDC in Action] 3. 基于OIDC(OpenID Connect)的SSO(添加Github OAuth 2.0的支持)
  • [one_demo_17]使用传统方式实现线程间通信的例子
  • [OS-Linux] CentOS 7.x 使用密钥登录安全设置
  • [Power Query] 分组依据
  • [PTP][1588v2] Follow_Up消息
  • [SDUT](3361) 数据结构实验之图论四:迷宫探索 ---DFS(图)
  • [StartingPoint][Tier1]Crocodile
  • [XA]我们为什么不用XP(eXtreme Programming)极限编程?
  • [ZJOI2019]语言