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 爬虫能接收从命…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
