shell 函数详解

news2024/9/21 19:07:25

目录

函数

一,什么是函数

二, 函数的返回值

三,函数语法

示例1:

示例2:

四,函数的调用

示例1:

示例2:

五,函数库文件

六, 递归函数

示例1:

示例2:


函数

一,什么是函数

1、把相同的程序段定义为函数,可以减少整个程序段代码量,提升开发效率。

2、增加程序段可读性、易读性,提升管理效率。

3、可以实现程序功能模块化,使得程序具备通用性(可移植性)。

二, 函数的返回值

       首先,用户可以使用return语句来返回某个数值,这与绝大部分的程序设计语言是相同的。但是,在Shell中,return语句只能返回某个0~255之间的整数值。

       在函数中,用户将需要返回的数据写入到标准输出(stdout),通常这个操作是使用echo语句来完成的。然后在调用程序中将函数的执行结果赋给一个变量。这种做法实际上就是命令替换的一个变种。

三,函数语法

function 函数名() {

指令

Return                        返回函数的退出码:echo $?

}

简化写法1:

function 函数名 {

指令

return

}

简化写法2:

函数名() {

指令

return

}

示例1:

编写脚本文件定义函数并调用函数,执行脚本文件

1,使用 vim function_script.sh 命令打开脚本文件

[root@wangjingjing ~]# vim function_script.sh

2,在脚本文件中定义函数并调用函数

#使用三种不同的方法定义函数

function print_info1 () {

    echo "This is func1"

    return 111

}

function print_info2 {

    echo "This is func2"

    return 222

}

print_info3 () {

    echo "This is func3"

    return 333

}

#调用函数,并打印函数的返回值,直接是命令

print_info1

echo "$?"

print_info2

echo "$?"

print_info3

echo "$?"

3,使命命令  bash function_script.sh  执行脚本,结果如下:

[root@wangjingjing ~]# bash function_script.sh

This is func1

111

This is func2

222

This is func3

77

示例2:

在脚本refer_script.sh 中调用脚本 function_script.sh中的函数

1,使用命令  vim function_script.sh 打开脚本文件

[root@wangjingjing ~]# vim function_script.sh

2,定义函数

#使用三种不同的防范定义函数

function print_info1 () {

    echo "This is func1"

    return 111

}

function print_info2 {

    echo "This is func2"

    return 222

}

print_info3 () {

    echo "This is func3"

    return 333

}

3,使用命令  vim refer_script.sh  打开脚本文件

[root@wangjingjing ~]# vim refer_script.sh

4,在新的脚本文件中的调用之前定义的函数

#调用函数

. function_script.sh

#执行函数

print_info1

print_info2

print_info3

5,使用命令  bash refer_script.sh  执行新的脚本文件,结果如下:

[root@wangjingjing ~]# bash refer_script.sh

This is func1

This is func2

This is func3

四,函数的调用

在Shell中,函数调用的基本语法如下:

function_name param1 param2 …

        在上面的语法中,function_name表示函数名称,其后面跟的param1、param2…表示函数的参数。Shell的函数参数的语法比较特殊。实际上,Shell将脚本参数和函数参数做了统一地处理。也就是说,Shell采用了相同的方法来处理脚本的参数和函数参数。

(1)调用函数:直接执行函数名即可。

        函数名

(2)带参数的函数执行方法:

        函数名 参数

        与Shell脚本一样,用户可以在Shell函数中使用位置变量来获取参数值。例如,$0表示脚本名称,$#来获取函数的参数个数,$1表示第1个参数,$2表示第2个参数等,以此类推。另外,用户还可以通过系统变量$@和$*获取所有参数的值。

示例1:

调用函数:直接执行函数名即可。

1,使用命令  vim function_script.sh  打开脚本文件

[root@wangjingjing ~]# vim function_script.sh

2,定义函数并直接执行函数名

#使用三种不同的方法定义函数

function print_info1 () {

    echo "This is func1"

    return 111

}

function print_info2 {

    echo "This is func2"

    return 222

}

print_info3 () {

    echo "This is func3"

    return 333

}

function arg_info4 () {

#打印脚本名,不是函数名

    echo "$0"

#打印第一个参数

    echo "$1"

#打印第二个参数

    echo "$2"

    echo "$3"

}

#调用函数

print_info1

print_info2

print_info3

#调用函数并传入参数

arg_info4 1 2 3

3,使用命令  bash function_script.sh  执行脚本文件,结果如下:

[root@wangjingjing ~]# bash function_script.sh

This is func1

This is func2

This is func3

function_script.sh

1

2

3

示例2:

写一个脚本,使用函数完成

函数能够接受一个参数,参数为用户名;

判断一个用户是否存在

如果存在,就返回此用户的shell和UID;并返回正常状态值;

如果不存在,就说此用户不存在;并返回错误状态值;

1,使用命令 vim isname_exist.sh 打开脚本文件

[root@wangjingjing ~]# vim isname_exist.sh

2,定义函数,使用脚本传参调用函数

user_name=$1

#如果用户存在;返回0

#如果用户不存在;返回1

function isuser_exist() {

    grep ^"$1:" /etc/passwd &> /dev/null

    ret_val=$?

    if [ $ret_val -eq 0 ]

    then

#在/etc/passwd文件里找以$1:开始的并用:断开,取出第三段(uid)和第七段(shell)

        echo `grep ^"$1:" /etc/passwd | cut -d ":" -f3,7`

        return 0

    else

        echo "User is not exist"

        return 1

    fi

}

#调用函数,从脚本传参

isuser_exist $1

   echo "$?"

3,使用命令  bash isname_exist.sh +用户  执行脚本文件,结果如下:

[root@wangjingjing ~]# bash isname_exist.sh redhat

1000:/bin/bash

0

[root@wangjingjing ~]# bash isname_exist.sh user0001

User is not exist

1

五,函数库文件

为了方便地重用这些功能,可以创建一些可重用的函数。这些函数可以单独地放在函数库文件中。

函数库文件定义:

       创建一个函数库文件的过程非常类似于编写一个Shell脚本。脚本与库文件之间的唯一区别在于函数库文件通常只包括函数,而脚本中则可以既包括函数和变量的定义,又包括可执行的代码。此处所说的可执行代码,是指位于函数外部的代码,当脚本被载入后,这些代码会立即被执行,毋需另外调用。

函数库文件的调用

       当库文件定义好之后,用户就可以在程序中载入库文件,并且调用其中的函数。在Shell中,载入库文件的命令为.,即一个圆点,其语法如下:

. filename

        其中,参数filename表示库文件的名称,必须是一个合法的文件名。库文件可以使用相对路径,也可以使用绝对路径。另外,圆点命令和库文件名之间有一个空格。

六, 递归函数

        Linux的Shell也支持函数的递归调用。也就是说,函数可以直接或者间接地调用自身。在函数的递归调用中,函数既是调用者,又是被调用者。

递归函数的调用过程就是反复地调用其自身,每调用一次就进入新的一层。

示例1:

用函数实现阶乘原理

1,使用命令   vim factorial_script.sh   打开脚本文件

[root@wangjingjing ~]# vim factorial_script.sh

2,定义函数

factorial() {

    n=$1

    if [ $n -eq 1 ]

    then

#f(1)=1

        echo 1

    else

#当n大于1时,f(n)=f(n-1)*n

        echo $((`factorial $((n-=1))` * n))

    fi

}

factorial $1

3,使用命令  bash factorial_script.sh 5 求5的阶乘,结果如下:

[root@wangjingjing ~]# bash factorial_script.sh 5

120

示例2:

编写函数脚本,求1+2+…+100的和

1,使用命令  vim sum_script.sh   打开脚本文件

[root@wangjingjing ~]# vim sum_script.sh

2,定义函数

sum() {

    n=$1

    if [ $n -eq 1 ]

    then

        echo 1

    else

        echo $(( `sum $((n-=1))` + n ))

    fi

}

sum $1

3,使用命令 bash sum_script.sh 100 执行文件,结果如下:

[root@wangjingjing ~]# bash sum_script.sh 100
5050

 

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

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

相关文章

Node.js 全局对象介绍

在学习 Javascript 之初,会接触一个概念:JS 由三部分组成,DOM BOM ECMAScript。其中前两者是宿主环境,也就是浏览器所提供的能力。后者才是 JS 语言本身的标准。 在上篇文章《Node.js入门(1)&#xff1a…

SpringMVC之响应

目录 一:环境准备 二:响应页面[了解] 三:返回文本数据[了解] 四:响应JSON数据 SpringMVC接收到请求和数据后,进行一些了的处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的…

1月更新!EasyOps® 28+新功能“狂飙”上线~

2023节后,我们就要“搞事情”! 一波新功能已上线,快看是不是你需要的! 持续升级优化全平台产品, 只为成为你数字化变革最值得信赖的合作伙伴! 优维EasyOps全平台28新功能来了! ↓↓↓ 1、H…

Spring的后处理器之BeanFactoryPostProcessor

Spring的后处理器 Spring的后处理器是Spring对外开放的重要扩展点,允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用。Spring主要有两种后处理器&#xff1…

【车载开发系列】StatusOfDTC的解析

【车载开发系列】StatusOfDTC的解析 StatusOfDTC的解析【车载开发系列】StatusOfDTC的解析StatusOfDTC概念StatusOfDTC列表StatusOfDTC状态掩码Bit 0: TestFailedBit 1: testFailedThisOperationCycleBit 2: pendingDTCBit 3: confirmedDTCBit 4: testNotCompletedSinceLastCle…

【操作系统】3、内存管理

文章目录三、内存管理3.1 内存基础3.1.1 内存管理概念3.1.2 程序装入与链接3.1.3 内存保护3.2 内存空间的分配与回收3.2.1 连续分配管理方式3.2.1.1 单一连续分配3.2.1.2 固定分区分配3.2.1.3 动态分区分配3.2.2 动态分区分配算法3.2.2.1 首次适应算法3.2.2.2 最佳适用算法3.2.…

【数据库原理与SQL Server应用】Part05——表和表数据操作

【数据库原理与SQL Server应用】Part05——表和表数据操作一、表概念1.1 表结构1.2 表类型1.3 数据类型二、创建表2.1 管理工具界面方式创建表2.2 命令行方式创建表三、修改表3.1 管理工具界面方式修改表3.2 命令行方式修改表四、删除表五、表数据操作5.1 管理工具界面方式操作…

怎么快速选择出色的香港服务器

相信一些大规模企业或站长都不满足于普通的香港VPS,虽然它也拥有很不错的性能与速度,但远远比不上香港服务器。但是,对于初次使用香港服务器的用户来说,选择起来肯定是要经过一番考虑的,那么,有没有什么简单…

电子词典项目

16. 电子词典项目需求 项目要求: 登录注册功能,不能重复登录,重复注册单词查询功能历史记录功能,存储单词,意思,以及查询时间基于TCP,支持多客户端连接采用数据库保存用户信息与历史记录将dic…

VS2022离线安装教程

官方教程下载和安装步骤 https://docs.microsoft.com/zh-cn/visualstudio/install/create-an-offline-installation-of-visual-studio?viewvs-2022 使用命令行创建本地布局 下载所需的 Visual Studio 版本的引导程序,并将其复制到要用作本地布局源位置的目录中。…

训练自己的GPT2模型(中文),踩坑与经验

GPT2与Bert、T5之类的模型很不一样!!! 如果你对Bert、T5、BART的训练已经很熟悉,想要训练中文GPT模型,务必了解以下区别!!! 官方文档里虽然已经有教程,但是都是英文&…

手撸低代码平台搭建(四)组件拖动自由布局的实现

前言 大家好,在前两篇文章中,我们走进了前端低代码的世界,并揭秘了低代码的核心——页面设计器的实现。在揭秘页面设计器时,我们重点分享了顺序排列布局的组件拖动方式,那篇文章的评论中,有小伙伴问到自由布局的实现,那么我们在这篇文章中来分享一下自由布局拖动的实现…

Echarts柱形头部圆弧处理

第008个点击查看专栏目录对于柱状图来说,我们想要的效果是圆柱的上面进行圆弧的处理,产生顺滑的感觉,怎么处理呢,只要设置好样式即可,参考源代码圆角半径,单位px,支持传入数组分别指定 4 个圆角…

VMware 多站点容灾之SRM部署实践

一、背景 在VMware 多云场景中,我们最初会通过vmware的副本机制手动克隆或主从模式完成一些节点的灾备,虽然在初期不会出现什么问题,但一旦出现灾备恢复的复杂度和数据丢失风险还是一大考验,基于此,我们可借助VMware v…

Qt 获取网络信息

在Qt Network模块中使用QHostAddress存放IP地址,QHostInfo类来获取主机名和IP。 进行TCP/UDP编程时,需要将连接的主机名解析为IP地址,这个操作用DNS协议执行。 在互联网中现在有两种IP类型:IVP4和IVP6。 IP地址是给每一个连接在互…

Linux操作系统之基础IO

目录 系统IO调用接口 open write read 理解文件描述符fd 理解Linux操作系统的设计哲学,多态的思想是如何应用在Linux文件系统的 输出,追加,输入重定向的本质 子进程共享父进程的文件 IO的两个缓冲区 Linux特有的EXT文件系统 磁盘系…

代码训练营第二十天|530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先

530 .二叉搜索树的最小绝对差 看完题后的思路 因为是二叉搜索树,所以直接按照二叉搜索树中序遍历,得到递增序列。遍历过程中一个指针指向遍历过的前一个元素 prenull; void f(root)if rootnull return递归 f&#x…

git语义化定制版本规范

目录说明说明 语义化版本控制规范,语义化的版本控制规范要求版本号由三部分构成:x.y.z MAJOR(X):这个是主版本号,一般是涉及到不兼容的 API 更改时,这个会变化。MINOR(Y)&#xff…

剑指Offer pow() 函数实现(快速幂)!!!

剑指 Offer 16. 数值的整数次方 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。 示例 1: 输入:x 2.00000, n 10 输出:1024.00000 示…

早已有所耳闻的堆排序,你知道如何用C语言实现吗? 【堆排序|C语言版】

目录 0.写在前面 1.什么是堆? 2. 堆排序 2.1 建堆 2.1.1 AdjustUp(向上调整算法) 2.1.2 AdjustDown(向下调整算法) 2.2 两种建堆算法的时间复杂度 2.2.1 AdjustUp建堆的时间复杂度 2.2.2 AdjustDown建堆的时间…