Linux函数
目录
一、脚本函数
1.1 创建函数
1.2 使用函数
二、函数返回值
2.1 默认的退出状态码
2.2 使用return命令
2.3 使用函数输出
三、在函数中使用变量
3.1 向函数传达参数
3.2 在函数中处理变量
四、数组变量和函数
4.1 向函数中传递数组
4.2 从函数中返回数组
五、函数递归
一、脚本函数
1.1 创建函数
在bash shell脚本中创建函数的语法有两种。第一种是使用关键字function,随后跟上分配给该代码块的函数名:
function name {commands
}
name 定义了该函数的唯一名称。脚本中函数名不能重复。
第二种创建函数的方法:
name() {commands
}
函数名后的空括号表明正在定义的是一个函数。
1.2 使用函数
要在脚本中使用函数,只需写出函数名即可。
函数定义不一定非要放在shell脚本的最开始部分,但是要在调用函数之前定义函数。
如果定义了同名函数,那么新定义的就会覆盖函数原先的定义,而这一切不会有任何错误信息。
二、函数返回值
2.1 默认的退出状态码
在默认情况下,函数的退出状态码是函数中最后一个命令返回的退出状态码。函数执行结束后,可以使用标准变量 $? 来确认函数的退出状态码
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {echo "该条命令正常执行,退出状态码是0"ls notexist_file
}
echo "测试函数"
func1
echo "函数退出状态码是:$?"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
测试函数
该条命令正常执行,退出状态码是0
ls: cannot access notexist_file: No such file or directory
函数退出状态码是:2
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
该函数的退出状态码是 2 ,因为函数中的最后一条命令执行失败了。但是你无法知道该函数中其他命令是否执行成功。看下面例子:
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {ls notexist_fileecho "该条命令正常执行,退出状态码是0"
}
echo "测试函数"
func1
echo "函数退出状态码是:$?"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
测试函数
ls: cannot access notexist_file: No such file or directory
该条命令正常执行,退出状态码是0
函数退出状态码是:0
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
这次由于函数中最后一条命令执行成功,所以函数的退出状态码是 0 ,不过其中的其他命令执行失败。使用函数默认退出状态码是一种危险的行为。
2.2 使用return命令
bash shell会使用return命令以特定的状态码退出函数。return 命令允许指定一个整数值作为函数的退出状态码。但是用这种方法返回退出状态码一定注意两个问题:1)函数执行一结束就立刻读取返回值;2)退出状态码必须介于0-255,如下所示:
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {read -p "请输入一个整数:" valuereturn $[ $value * 2 ]
}
func1
echo "函数退出状态码是:$?"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
请输入一个整数:4
函数退出状态码是:8
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
请输入一个整数:200
函数退出状态码是:144
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
2.3 使用函数输出
正如可以将命令的输出保存到 shell 变量中一样,也可以将函数的输出保存到 shell 变量中,如下:
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {read -p "请输入一个整数:" valueecho $[ $value * 2 ]
}
result=$(func1)
echo "函数退出状态码是:$result"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
请输入一个整数:255
函数退出状态码是:510
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
注意函数中 echo $[ $value * 2 ],而非return $[ $value * 2 ]
这个例子演示了一个不易察觉的技巧。注意,函数func1实际上输出了两条信息,read 命令输出了一条简短的提示消息。bash shell 非常聪明,并不将其作为STDOUT输出的一部分,而是直接将其忽略。如果用 echo 语句生成这条消息来询问用户,那么他就会与输出值一起被读入shell 变量。
注意 这种方法还可以返回浮点值和字符串,这使其成为一种获取函数返回值的强大方法。
三、在函数中使用变量
3.1 向函数传达参数
注意 在脚本中调用函数时,必须将参数和函数名放在同一行。
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {if [ $# -eq 0 ] || [ $# -gt 2 ]thenecho -1elif [ $# -eq 1 ]thenecho $[ $1 + $1 ]elseecho $[ $1 + $2 ]fi
}
echo -n "传入2个参数:"
value=$(func1 10 11)
echo $value
echo -n "传入1个参数:"
value=$(func1 10)
echo $value
echo -n "传入3个参数:"
value=$(func1 10 11 12)
echo $value
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
传入2个参数:21
传入1个参数:20
传入3个参数:-1
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
要在函数中使用脚本的命令行参数,必须在调用函数时将其手动传入
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh 1 2
function.sh: line 4: + : syntax error: operand expected (error token is "+ ")[root@iZbp1ir1vzqwzkdy7mvjthZ ~]## 手动传入脚本的命令行参数[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {echo $[ $1 + $2 ]
}
echo $(func1 $1 $2)[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh 12 42
54
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
3.2 在函数中处理变量
无须在函数中使用全局变量,任何在函数内部使用的变量都可以被声明为局部变量。为此,只需在变量声明之前加上 local 关键字,如下示例:
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {temp=$[ $value + 6 ]result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
thenecho "temp is larger"
elseecho "temp is smaller"
fi
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
The result is 24
temp is larger
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
输出的结果是temp大于values,就是因为函数中使用了temp变量,因此它的值在脚本中受到了影响,产生了意想不到的结果。一种解决的办法是函数中使用局部变量,如下示例:
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {local temp=$[ $value + 6 ]result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
thenecho "temp is larger"
elseecho "temp is smaller"
fi
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
The result is 24
temp is smaller
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
四、数组变量和函数
4.1 向函数中传递数组
向脚本函数传递数组变量的方法有点难以理解。将数组变量当作单个参数传递的话,他不起作用。
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {echo "传递的参数是:$@"this_arry=$1echo "传入的数组是:${this_arry[*]}"}
arry=(1 2 3 4)
echo "原始数组是:${arry[*]}"
func1 $arry
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
原始数组是:1 2 3 4
传递的参数是:1
传入的数组是:1
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
可以看出,将数组变量作为函数参数进行传递,则函数只会提取数组变量的第一个元素。要解决这个问题,必须将数组变量拆解成多个数组元素,然后将这些数组元素作为函数参数传达。最后在函数内部,将所有的参数重组为一个新的数组变量。示例如下:
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {echo "传递的参数是:$@"local new_arry=(`echo "$@"`)echo "新数组是:${new_arry[*]}"
}
arry=(1 2 3 4)
echo "原始数组是:${arry[*]}"
func1 ${arry[*]}
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
原始数组是:1 2 3 4
传递的参数是:1 2 3 4
新数组是:1 2 3 4
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
4.2 从函数中返回数组
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {local org_arry=(`echo "$@"`)local ielements=$[ $# - 1 ]for (( i=0;i<=$elements;i++ ))dolocal new_arry[$i]=$[ ${org_arry[$i]} * 2 ]doneecho "新数组是:${new_arry[*]}"
}
arry=(1 2 3 4)
echo "原始数组是:${arry[*]}"
func1 ${arry[*]}
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
原始数组是:1 2 3 4
新数组是:2 4 6 8
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
五、函数递归
局部函数变量的一个特性是自成体系。除了获取函数参数外,自成体系的函数不需要任何外部资源。这个特性使得函数可以递归调用,也就是说函数可以调用自己得来的结果。递归函数通常有一个最终可以迭代到的基准值。
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat function.sh
#! /bin/bashfunc1() {if [ $1 -eq 1 ]thenecho 1elselocal temp=$[ $1 -1 ]local result=$(func1 $temp)echo $[ $result * $1 ]fi
}
read -p "阶乘数:" value
result=$(func1 $value)
echo "$value阶乘的结果是:$result"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# bash function.sh
阶乘数:6
6阶乘的结果是:720
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#
相关文章:
Linux函数
目录 一、脚本函数 1.1 创建函数 1.2 使用函数 二、函数返回值 2.1 默认的退出状态码 2.2 使用return命令 2.3 使用函数输出 三、在函数中使用变量 3.1 向函数传达参数 3.2 在函数中处理变量 四、数组变量和函数 4.1 向函数中传递数组 4.2 从函数中返回数组 五、函数…...
如何查看centos7中Java在哪些路径下
在 CentOS 7 上,你可以通过几种方式查找安装的 Java 版本及其路径。以下是一些常用的方法: 1. 使用 alternatives 命令 CentOS 使用 alternatives 系统来管理同一命令的多个版本。你可以使用以下命令来查看系统上所有 Java 安装的配置: su…...
信息安全-古典密码学简介
目录 C. D. Shannon: 一、置换密码 二、单表代替密码 ① 加法密码 ② 乘法密码 ③密钥词组代替密码 三、多表代替密码 代数密码 四、古典密码的穷举分析 1、单表代替密码分析 五、古典密码的统计分析 1、密钥词组单表代替密码的统计分析 2、英语的统计规…...
面试题 01.05. 一次编辑
字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。 示例 1: 输入: first "pale" second "ple" 输出: True示例 2: 输入: first &qu…...
针对头疼的UDP攻击如何定制有效的防护措施
分布式拒绝服务攻击(Distributed Denial of Service)简称DDoS,亦称为阻断攻击或洪水攻击,是目前互联网最常见的一种攻击形式。DDoS攻击通常通过来自大量受感染的计算机(即僵尸网络)的流量,对目标…...
怎么制作流程图?介绍制作方法
怎么制作流程图?在日常生活和工作中,流程图已经成为我们不可或缺的工具。无论是项目规划、流程优化,还是学习理解复杂系统,流程图都能帮助我们更直观地理解和表达信息。然而,很多人可能并不清楚,其实制作流…...
棱镜七彩参编《网络安全技术 软件供应链安全要求》国家标准发布
据全国标准信息公共服务平台消息显示,《网络安全技术 软件供应链安全要求》(GB/T 43698-2024)国家标准已于2024年4月25日正式发布,并将于2024年11月1日正式实施。棱镜七彩作为主要编制单位之一参与该国家标准的编制,为…...
Keepalived实现LVS高可用
6.1 KeepalivedLVS集群介绍 Keepalived和LVS共同构建了一个高效的负载均衡和高可用性解决方案:LVS作为负载均衡器,负责在集群中的多个服务器间分配流量,以其高性能和可扩展性确保应用程序能够处理大量的并发请求;而Keepalived则作…...
【力扣】1089.复写零
原题链接:. - 力扣(LeetCode) 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。 注意:请不…...
Golang实践录:gin框架使用自定义日志模块
本文介绍在 Golang 的 gin 框架中使用自定义日志模块的一些方法。 背景 很早之前就实现并使用了自己封装的日志模块,但一直没有将gin框架内部的日志和日志模块结合。gin的日志都是在终端上打印的,排查问题不方便。趁五一假期,集中研究把此事…...
Django之配置数据库
一,创建项目 二,将项目的setting.py中的 DATABASES {default: {ENGINE: django.db.backends.sqlite3,NAME: BASE_DIR / db.sqlite3,} }替换成如下(以mysql为例) DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: …...
Ajax 笔记02
01 jq中的ajax方法中的dataType属性 dataType属性的属性值有以下几种: xml 返回数据按照xml解析 json 返回的数据按照json代码解析 script 返回的数据按照js代码解析 text 把返回的数据按照普通文本解析 jsonp 跨域 json: javascript object notation(js对象简谱) json整体…...
【隧道篇 / WAN优化】(7.4) ❀ 03. WAN优化的原理 ❀ FortiGate 防火墙
【简介】相信对WAN优化感兴趣的人都会有疑问,WAN优化真的有作用吗?如果真的有作用,那是根据什么原理呢?让我们来更深入的了解一下。 客户端和服务器端 其实很多人在一开始看到WAN优化这个词,就自然的以为上网速度太慢&…...
网络爬虫概述与原理
网络爬虫概述与原理 网络爬虫简介狭义上理解功能上理解常见用途总结 网络爬虫分类通用网络爬虫聚焦网络爬虫增量网络爬虫深度网络爬虫 网络爬虫流程网络爬虫采集策略深度有限搜索策略广度优先搜索策略 网络爬虫简介 通过有效地获取网络资源的方式,便是网络爬虫。网…...
可视化实验三 Matplotlib库绘图及时变数据可视化
1.1 任务一 1.1.1 恢复默认配置 #绘图风格,恢复默认配置 plt.rcParams.update(plt.rcParamsDefault)#恢复默认配置 或者 plt.rcdefaults() 1.1.2 汉字和负号的设置 import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"]"SimH…...
开启多线程下变量共享与私有问题
开启多线程下变量共享与私有问题 🌵ThreadLocal和Atomic是Java中用于多线程编程的两个重要工具。 ThreadLocal是一个线程局部变量,它为每个线程提供了独立的变量副本,确保每个线程都可以访问自己的变量副本而不会影响其他线程的变量。在多线…...
Qt模型视图代理之QTableView应用的简单介绍
往期回顾 Qt绘图与图形视图之绘制带三角形箭头的窗口的简单介绍-CSDN博客 Qt绘图与图形视图之Graphics View坐标系的简单介绍-CSDN博客 Qt模型视图代理之MVD(模型-视图-代理)概念的简单介绍-CSDN博客 Qt模型视图代理之QTableView应用的简单介绍 一、最终效果 二、设计思路 这里…...
第七届精武杯部分wp
第一部分:计算机和手机取证 1.请综合分析计算机和手机检材,计算机最近一次登录的账户名是 答案:admin 创建虚拟机时直接给出了用户名 2. 请综合分析计算机和手机检材,计算机最近一次插入的USB存储设备串号是 答案:…...
3.2Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3框架-企业级应用- Vuex
Vuex简介 Vuex概述 Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规 则保证状态以一种可预测的方式发生变化. 试想这样的场景, 比如一个Vue的根实例下面有一个根组件名为App.vue, 它下面有两个子组件A.vue和B.vu…...
整合 Java, Python 和 Scrapy 爬虫以传递和使用参数
这篇博客将详细说明如何从 Java 应用程序调用一个 Python 脚本,并在此过程中传递参数给一个 Scrapy 爬虫。最终目标是让 Java 控制爬虫的行为,如爬取数量和特定的运行参数。 一、Scrapy 爬虫的修改 首先,我们需要确保 Scrapy 爬虫能接收从命…...
Kubernetes 存储性能优化:从持久卷到存储类
Kubernetes 存储性能优化:从持久卷到存储类 前言 哥们,别整那些花里胡哨的理论。今天直接上硬菜——我在大厂一线优化 Kubernetes 存储性能的真实经验总结。作为一个白天写前端、晚上打鼓的硬核工程师,我对性能的追求就像对鼓点节奏的把控一样…...
**发散创新:用Python + ROS2实现多机器人协同路径规划与避障控制**在现代机器人系统中,**
发散创新:用Python ROS2实现多机器人协同路径规划与避障控制 在现代机器人系统中,多机器人协同控制已成为智能仓储、物流配送和工业自动化的核心技术之一。本文将带你深入一个真实可运行的案例——使用 Python 语言结合ROS2(Robot Operating…...
HunyuanVideo-Foley效果展示:AI生成的量子计算实验室环境音效(科技感)
HunyuanVideo-Foley效果展示:AI生成的量子计算实验室环境音效(科技感) 1. 核心能力概览 HunyuanVideo-Foley是一款专为视频与音效生成设计的AI模型,其私有部署镜像经过RTX 4090D 24GB显卡的深度优化。这个镜像最令人惊艳的能力之…...
SeqGPT-560M中文理解深度测评:对古汉语、方言、行业黑话的泛化能力分析
SeqGPT-560M中文理解深度测评:对古汉语、方言、行业黑话的泛化能力分析 1. 模型背景与核心能力 SeqGPT-560M是阿里达摩院推出的零样本文本理解模型,专门针对中文场景优化,无需训练即可完成文本分类和信息抽取任务。这个560M参数的轻量级模型…...
java rabbitmq实现消息协作
场景:数据下载采用rpa实现,数据服务采用java springboot实现,需要进行一键数据补录操作1、设置消息承载的通信队列,java 发送任务到rabbitmq和rpa端收到消息(neimeng_data_download)后,将下载结…...
SEO_避开这些常见误区,让你的SEO效果翻倍
<h2>避开这些常见误区,让你的SEO效果翻倍</h2> <p>在当今的互联网时代,搜索引擎优化(SEO)已经成为了每个网站和博客运营者必须掌握的技能之一。许多人在进行SEO时却会犯一些常见的错误,这些错误不仅…...
MPC模型下四节电池SOC均衡控制技术:全网首发的效果超群解决方案
MPC模型预测控制四节电池SOC均衡 [1]全网首发电池SOC均衡控制,当前领域国内期刊罕有有人发。 [2]效果超群,根据电池均衡路径完美规划均衡电流,电流由大到小,避免均衡后期均衡路径问题。电池均衡这玩意儿听着高大上,说白…...
轻量级MCU命令行交互系统设计与优化
1. 轻量级MCU命令行交互系统设计指南1.1 系统概述在嵌入式系统开发过程中,调试和维护阶段往往需要与单片机进行参数交互和操作控制。传统解决方案如RT-Thread的finsh组件虽然功能强大,但对于资源受限的MCU(如ROM<64KB,RAM<8…...
CANoe实战:手把手教你用J1939.dbc发送超8字节长帧报文(附完整CAPL代码)
CANoe实战:J1939长帧报文分包发送全解析与CAPL代码优化 在汽车电子开发领域,J1939协议作为商用车通信标准,其长帧报文处理一直是工程师面临的典型挑战。当数据长度超过CAN总线单帧8字节限制时,如何高效实现分包传输?本…...
SVG-Edit:开源矢量编辑在浏览器工具中的创新实践
SVG-Edit:开源矢量编辑在浏览器工具中的创新实践 【免费下载链接】svgedit Powerful SVG-Editor for your browser 项目地址: https://gitcode.com/gh_mirrors/sv/svgedit SVG-Edit是一款基于浏览器环境的开源矢量图形编辑工具,提供在线SVG编辑能…...
