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 爬虫能接收从命…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
