【Linux】函数
一、函数
1、创建函数
如果定义了同名函数,则新定义的函数就会覆盖原先的定义的函数,而且在运行时不会报错。
创建函数的语法:
方法1:使用关键字function
function name {
commands
}
shell脚本中的函数名不能重复
方法2:
name() {
commands
}
函数名后的空括号name()表明正在定义的是一个函数。
2、使用函数
不能在函数定义之前调用函数,否则会报错。
#!/bin/bashfunction test {echo "测试123456"
}count=1
while [ $count -le 5 ]
dotestcount=$[ $count + 1 ]
done
echo "循环结束!"
test
echo "脚本运行结束!"
exit

3、函数返回值
使用退出状态码
默认情况下,函数的退出状态码是函数中最后一个命令返回的退出状态码。函数执行结束后,可以使用标准变量 $? 来确定函数的退出状态码。
#!/bin/bashfunc1() {echo "尝试展示不存在的文件。"ls -l badfile
}echo "测试函数:"
func1
echo "退出状态码是:$?"
如下所示,退出状态码是2,因为函数中的最后一个命令执行失败了,但 echo 命令却执行成功了。 所以,使用退出状态码的方法是一种危险的方法。

使用return命令
bash shell会使用return命令以特定的退出状态码退出函数;return命令允许指定一个整数值作为函数的退出状态码。
#!/bin/bashfunc2() {read -p "请输入一个数值:" valueecho "将输入的数值翻倍。"return $[ $value * 2 ]
}func2
echo "新的值是 $?"
exit

当用此方法获取返回值时,需注意两点:
函数执行一结束就立刻读取返回值:如果在用$?变量提取函数返回值之前执行了其它命令,那么函数返回值就会丢失。$?变量保存的是最后执行的那个命令的退出状态码。
退出状态码必须在0~255范围内:因为退出状态码必须小于256,因此函数结果也必须是一个小于256的整数值,如果大于256就会产生错误的值。

使用函数输出
#!/bin/bashfunc3() {read -p "请输入一个数值:" valueecho "将输入的数值翻倍。"echo $[ $value * 2 ] # 注意不是return
}result=$(func3)
echo "新的值是$result"
exit

4、向函数传递参数
函数可以使用标准的位置变量来表示命令行中传给函数的任何参数,如函数名保存在$0变量中,函数参数依次保存在$1、$2等变量中。也可以使用特殊变量$#来确定传给函数的参数数量。
在shell脚本中调用函数时,必须将参数和函数名放在同一行。
用位置变量获取参数值
#!/bin/bashfunction func4 {if [ $# -eq 0 ] || [ $# -gt 2 ]thenecho -1elif [ $# -eq 1 ]thenecho $[ $1 + $1 ]elseecho $[ $1 + $2 ]fi
}echo -n "传递两个参数:"
value=$(func4 10 15)
echo $valueecho -n "只传递一个参数:"
value=$(func4 20)
echo $valueecho -n "不传递参数:"
value=$(func4)
echo $valueecho -n "传递3个参数:"
value=$(func4 10 20 36)
echo $value

要想在函数中使用脚本的命令行参数,必须在调用函数时手动将其传入。
func5() {echo $[ $1 * $2 ]
}if [ $# -eq 2 ]
thenvalue=$(func5 $1 $2)echo "结果是$value."
elseecho "错误。"

5、函数中的变量
全局变量
全局变量在shell脚本内任何地方都有效的变量。
在默认情况下,在脚本中定义的任何变量都是全局变量。在函数外定义的变量可在函数内正常访问。
#!/bin/bashfunction func1 {value=$[ $value *2 ]
}read -p "请输入一个值:" value
func1
echo "新的值是 $value"

局部变量
任何在函数内部使用的变量都可以被声明为局部变量,只需在变量声明之前加上关键字 local 即可:local var
也可在变量赋值语句中使用 local 关键字:local var=$[ $value + 7 ]
local关键字保证了变量仅在函数中有效,如果函数外有同名变量,那么shell会保持这两个变量的值互不干扰,意味着可以轻松地将函数变量和脚本变量分离开。
#!/bin/bashfunction func2 {local temp=$[ $value + 10 ]result=$[ $temp * 2 ]
}temp=5
value=8func2
echo "结果是$result"
if [ $temp -gt $value ]
thenecho "temp更大"
elseecho "value更大"
fi

6、向函数传递数组
将数组变量当做单个参数传递的话,是不会起作用的。如果想要将数组变量作为函数参数进行传递,那么函数只会提取数组变量的第一个元素。
#!/bin/bashfunction func3 {echo "参数是:$@"thisarray=$1echo "接收到的数组是 ${thisarray[*]}"
}myarray=(1 2 3 4 5 6)
echo "原始数组是:${myarray[*]}"
func3 $myarray

传递数组变量时必须先将数组变量拆解成多个数组元素,然后将这些数组元素作为函数参数传递,最后在函数内部,将所有的参数重新组合成一个新的数组变量。
#!/bin/bashfunction func5 {local newarraynewarray=(`echo "$@"`)echo "新数组是:${newarray[*]}"
}myarray=(1 2 3 4 5 6)
echo "原始数组是:${myarray[*]}"
func5 ${myarray[*]}

#!/bin/bashfunction addarray {local sum=0local newarraynewarray=(`echo "$@"`)for value in ${newarray[*]}dosum=$[ $sum + $value ]doneecho $sum
}myarray=(1 2 3 4 5 6)
echo "原始数组是:${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=$(addarray $arg1)
echo "结果是 $result"

7、从函数返回数组
函数先用echo语句按正确顺序输出数组的各个元素,然后脚本再将数组元素重组成一个新的数组变量。
#!/bin/bashfunction arraydb {local origarraylocal newarraylocal elementlocal iorigarray=($(echo "$@")) newarray=($(echo "$@"))# "$@"会将每个参数作为独立的字符串保留element=$[ $# - 1 ] # $#表示参数数量for (( i = 0; i <= $element; i++ )){newarray[$i]=$[ ${origarray[$i]} * 2 ]}echo ${newarray[*]}
}myarray=(1 2 3 4 5 6)
echo "原始数组是:${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=($(arraydb $arg1))
echo "新数组是:${result[*]}"

8、函数递归
局部函数变量的一个特性是自成体系(self-containment),除了获取函数参数,自成体系函数不需要使用任何外部资源。这个特性使函数可以递归地调用,即函数通过调用自己得到结果。
递归函数通常有一个最终可以迭代到的基准值。
递归算法的经典例子就是计算阶乘。
#!/bin/bash
function factorial {if [ $1 -eq 1 ]thenecho 1elselocal temp=$[ $1 - 1 ]local result=$(factorial $temp)echo $[ $result * $1 ]fi
}read -p "请输入一个数值:" value
result=$(factorial $value)
echo "$value的阶乘是:$result"
exit

9、函数库
bash shell允许创建函数库文件,然后在多个shell脚本中引用此库文件。
可以通过 source 命令(也叫点号操作符)在shell脚本中运行库文件,它会在当前shell的上下文中执行命令,而不是创建新的shell并在其中执行命令。
格式:. ./绝对路径/函数库文件名
#!/bin/bash#创建一个函数库文件function addem {echo $[ $1 + $2 ]
}function multem {echo $[ $1 * $2 ]
}function divem {if [ $2 -ne 0 ]thenecho $[ $1 / $2 ]elseecho -1fi
}
在其它shell脚本中运行上面的函数库文件。
#!/bin/bash#用source命令允许库文件
. ./myfuncs.sh # 该函数库文件与此脚本在同一目录下value1=60
value2=20
result1=$(addem $value1 $value2)
echo "两数相加之和是:$result1"
result2=$(multem $value1 $value2)
echo "两数相乘之积是:$result2"
result3=$(divem $value1 $value2)
echo "两数相除之商是:$result3"

二、在命令行中使用函数
一旦在shell中定义了函数,就可以在整个系统的任意目录中使用,而不用担心该函数是否位于PATH环境变量中。
1、在命令行中创建函数
因为shell会解释用户输入的命令,所以可以在命令行中直接定义一个函数。缺点就是,在退出shell时,函数也会跟着消失
单行方式
使用单行方式定义函数时,需要在每个命令后面加分号,这样shell才能知道哪里是命令的起止。


多行方式
使用多行方式定义函数时,bash shell会使用次提示符来提示输入更多命令,此方法不需要再每条命令后面加分号,只需按下回车键即可。
当输入函数末尾的花括号 } 时,shell就能知道用户已经完成函数的定义了。

2、在.bashrc文件中定义函数
可以将函数定义在每次新shell启动时都会重新读取该函数的地方:.bashrc 文件。
不管是交互式shell还是从现有shell启动新的shell,bash shell在每次启动时都会在用户主目录中查找.bashrc文件。
直接定义函数
可以直接在用户主目录的.bashrc文件中定义函数。将函数直接放在末尾即可,如下所示。

此函数在下次启动新的bash shell时生效,然后就能在系统中的任意地方使用此函数。
源引函数文件
只要是在shell脚本中,就可以用source命令(点号操作符)将库文件中的函数添加到.bashrc脚本中,如下所示:

确保库文件的路径正确,下次重新启动bash shell时,就可以使用库中的所有函数。

也可以直接在shell脚本中使用,因为shell会将定义好的函数传给子shell进程,如此一来,这些函数就能够自动用于该shell会话中的任何shell脚本了。
#!/bin/bashvalue1=20
value2=5result1=$(addem $value1 $value2)
echo "两数之和是:$result1."
result2=$(multem $value1 $value2)
echo "两数之积是:$result2."
result3=$(divem $value1 $value2)
echo "两数之商是:$result3."
如下所示,执行脚本时报错,但能在交互式命令行执行。

相关文章:
【Linux】函数
一、函数 1、创建函数 如果定义了同名函数,则新定义的函数就会覆盖原先的定义的函数,而且在运行时不会报错。 创建函数的语法: 方法1:使用关键字function function name { commands } shell脚本中的函数名不能重复 方法2&#x…...
Maven中管理SNAPSHOT版本含义及作用
在开发过程中突然产生了一个疑问:IDEA中 maven deploy的依赖包的版本号,比如 1.0.0-SNAPSHOT是在哪配置的?在远程仓库中的版本和这个有关系吗 ? 在 Maven 中,-SNAPSHOT 后缀是用于标识项目版本为快照(Snapshot…...
win10 VS2019上libtorch库配置过程
win10 VS2019上libtorch库配置过程 0 引言1 获取libtorch2 在VS上配置使用libtorch库3 结语 0 引言 💻💻AI一下💻💻 libtorch库是一个用于深度学习的C库,是PyTorch的官方C前端。它提供了用于构建和训练深度学习模…...
【计算机网络】课程 实验二 交换机基本配置和VLAN 间路由实现
实验二 交换机基本配置和VLAN 间路由实现 一、实验目的 1.了解交换机的管理方式。 2.掌握通过Console接口对交换机进行配置的方法。 3.掌握交换机命令行各种模式的区别,能够使用各种帮助信息以及命令进行基本的配置。 4&…...
Oracle Dataguard(主库为单节点)配置详解(4):将主库复制到备库并启动同步
Oracle Dataguard(主库为单节点)配置详解(4):将主库复制到备库并启动同步 目录 Oracle Dataguard(主库为单节点)配置详解(4):将主库复制到备库并启动同步一、…...
OpenCL(贰):浅析CL内核程序接口函数
目录 1.前言 2.获取平台信息 1.cl_int类型 2.cl_platform_id类型 3.clGetPlatformIDs():查询系统OpenCL平台数量或获取具体的平台信息 4.clGetPlatformInfo():查询指定OpenCL平台的信息,例如平台名称、供应商、版本等 3.设置OpenCL上下文…...
Leetcode 3407. Substring Matching Pattern
Leetcode 3407. Substring Matching Pattern 1. 解题思路2. 代码实现 题目链接:3407. Substring Matching Pattern 1. 解题思路 这一题是一道leetcode easy的题目,照说应该没啥的,不过实际我做的时候在这里卡了一下,所以还是拿…...
学英语学压测:02jmeter组件-测试计划和线程组ramp-up参数的作用
📢📢📢:先看关键单词,再看英文,最后看中文总结,再回头看一遍英文原文,效果更佳!! 关键词 Functional Testing功能测试[ˈfʌŋkʃənəl ˈtɛstɪŋ]Sample样…...
Vue笔记-001-声明式渲染
https://cn.vuejs.org/tutorial/#step-2https://cn.vuejs.org/tutorial/#step-2 Vue 单文件组件 (Single-File Component,缩写为 SFC) 单文件组件是一种可复用的代码组织形式,它将从属于同一个组件的 HTML、CSS 和 JavaScript 封装在使用 .vue 后缀的文件…...
26考研资料分享 百度网盘
26考研资料分享考研资料合集 百度网盘(仅供参考学习) 基础班: 通过网盘分享的文件:2026【考研英语】等3个文件 链接: https://pan.baidu.com/s/1Q6rvKop3sWiL9zBHs87kAQ?pwd5qnn 提取码: 5qnn --来自百度网盘超级会员v3的分享…...
.NET 8 + Ocelot + Consul 实现代理网关、服务发现
.NET 8 Ocelot Consul 实现代理网关、服务发现 本文环境:.NET 8 Ocelot 23.4.2 Consul 1.7.14.6 1 实现网关 分别创建3个WebApi工程:OcelotGw、TestGwAService、TestGwBService;在OcelotGw工程中安装Ocelot包:Install-Packag…...
使用 Nginx 轻松处理跨域请求(CORS)
使用 Nginx 轻松处理跨域请求(CORS) 在现代 Web 开发中,跨域资源共享(CORS)是一种重要的机制,用于解决浏览器的同源策略限制。CORS 允许服务器声明哪些来源可以访问其资源,从而确保安全性与可用…...
【LeetCode Hot100 二分查找】搜索插入位置、搜索二维矩阵、搜索旋转排序数组、寻找两个正序数组的中位数
二分查找 搜索插入位置搜索二维矩阵在排序数组中查找元素的第一个和最后一个位置寻找旋转排序数组中的最小值搜索旋转排序数组寻找两个正序数组的中位数(hard) 搜索插入位置 给定一个排序数组和一个目标值,在数组中找到目标值,并…...
使用MediaPipe Face Mesh 面部动作检测
一、技术选型 OpenCV(Open Source Computer Vision Library) 用于视频流捕捉、图像预处理和基本图像处理操作。 MediaPipe 提供高效的人脸检测与关键点提取功能(Face Mesh)。 Python 作为后端开发语言,整合上述库进行…...
【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?
<script setup> 是 Vue 3 引入的一种新的脚本语法,它提供了一种更简洁和声明式的方式来编写组件逻辑。它是为了解决传统 <script> 标签在 Vue 单文件组件(SFC)中的一些局限性而设计的。 <script setup> 与 <script>…...
微服务框架,Http异步编程中,如何保证数据的最终一致性
一、背景 在微服务框架下,跨服务之间的调用,当遇到操作耗时或者量大的情况,我们一般会采用异步编程实现。 本文出现的问题是:异步回调过来时,却未查询到数据库中的任务,导致未能正常处理回调。 下面是当…...
vue3-dom-diff算法
vue3diff算法 什么是vue3diff算法 Vue3中的diff算法是一种用于比较虚拟DOM树之间差异的算法,其目的是为了高效地更新真实DOM,减少不必要的重渲染 主要过程 整个过程主要分为以下五步 前置预处理后置预处理仅处理新增仅处理后置处理包含新增、卸载、…...
年会抽奖Html
在这里插入图片描述 <!-- <video id"backgroundMusic" src"file:///D:/background.mp3" loop autoplay></video> --> <divstyle"width: 290px; height: 580px; margin-left: 20px; margin-top: 20px; background: url(D:/nianhu…...
ubuntu16 重启之后lvm信息丢失故障恢复
一、背景 1、问题背景 业务有一台物理开发服务器,文件系统有损坏;由于重启时没有检查,导致重启卡住。后面通过断电重新启动之后,无法进入系统;进入救援模式,注释数据盘挂载。重启之后进入系统,…...
【华为OD-E卷 - 热点网站统计 100分(python、java、c++、js、c)】
【华为OD-E卷 - 热点网站统计 100分(python、java、c、js、c)】 题目 企业路由器的统计页面,有一个功能需要动态统计公司访问最多的网页URL top N。请设计一个算法,可以高效动态统计Top N的页面 输入描述 每一行都是一个URL或…...
2026年口碑爆棚!昆明专业装修公司究竟哪家才是你的心头好?
在昆明,装修公司众多,如何选择一家靠谱的公司成为许多业主的难题。下面结合昆明装修行业的常见痛点,为大家推荐昆明装家汉工程设计有限公司(渤竣装家汉),并对比一些大厂,让你找到心仪的装修公司…...
别被“纯解释型语言”骗了:揭开 Python 运行机制的真实底牌
在编程语言的鄙视链中,Python 经常被贴上一个标签:“它只是一门解释型语言,所以它很慢。” 这种刻板印象往往来自于我们在命令行里敲下 python script.py 后它立即运行的爽快感。没有漫长的 make,没有 gcc 编译报错,仿…...
成果分享:用星图平台快速搭建的Qwen3-VL:30B飞书助手,办公效率翻倍
成果分享:用星图平台快速搭建的Qwen3-VL:30B飞书助手,办公效率翻倍 1. 项目概述与价值 1.1 为什么选择Qwen3-VL:30B 在当今办公场景中,处理图文混合内容的需求日益增长。传统AI助手往往只能处理单一模态的信息,而Qwen3-VL:30B作…...
一键部署语音情感识别AI:Emotion2Vec+ Large镜像开箱即用教程
一键部署语音情感识别AI:Emotion2Vec Large镜像开箱即用教程 1. 快速了解Emotion2Vec Large Emotion2Vec Large是一款基于深度学习的语音情感识别系统,能够准确识别9种人类情感状态。这个预置镜像由科哥团队二次开发优化,特别适合需要快速部…...
从零开始了解GXUI字体系统:完整解析字体嵌入与字形渲染流程
从零开始了解GXUI字体系统:完整解析字体嵌入与字形渲染流程 【免费下载链接】gxui An experimental Go cross platform UI library. 项目地址: https://gitcode.com/gh_mirrors/gx/gxui GXUI是一个实验性的Go跨平台UI库,其字体系统是实现高质量文…...
Laravel Cashier Stripe Webhook完整教程:实时处理支付事件
Laravel Cashier Stripe Webhook完整教程:实时处理支付事件 【免费下载链接】cashier-stripe Laravel Cashier provides an expressive, fluent interface to Stripes subscription billing services. 项目地址: https://gitcode.com/gh_mirrors/ca/cashier-strip…...
【毕业季求生帖】论文盲目降AI等于白送钱?10款降AI软件红黑榜揭秘
今年毕业季,降AI率最大的难点其实早就不仅是降不降得下来,还有降完之后还能不能看,随着知网、维普接连升级AIGC检测算法,靠简单同义词替换已经完全行不通了。 而且最让大家崩溃的往往是这三点:第一,降完之后…...
Arduino_CloudUtils:嵌入式物联网云通信核心工具库
1. Arduino_CloudUtils 库深度解析:嵌入式云通信核心工具链Arduino_CloudUtils 是 Arduino 官方为物联网云连接场景设计的底层通用工具库,其定位并非独立应用框架,而是作为 ArduinoIoTCloud 等上层云 SDK 的“基础设施层”。该库不处理网络协…...
Shell 性能监控:指标采集、告警规则与可视化大盘设计
一、前言Shell 性能监控:指标采集、告警规则与可视化大盘设计是运维工程师和全栈开发者的必备技能。本文从Shell和监控出发,配有完整的命令和脚本示例。二、常用命令速查2.1 系统监控# CPU 和内存使用 top -c htop # 更直观# 磁盘使用 df -h du -sh /* …...
镜像视界空间智能体系统的核心原理是否涉及人工智能技术?
一句话结论涉及人工智能,但本质不是AI系统。我们的核心是空间计算系统,AI只是其中一个工具层。🧠 分层拆解1️⃣ 底层:不是AI ——是空间几何计算系统最核心的能力是:空间反演(Pixel → World)多…...
