linux Shell编程之函数与数组(四)

目录

[一. shell 函数](#一. shell 函数)

[1. 函数的用法](#1. 函数的用法)

[(1) 两个数求和](#(1) 两个数求和)

[(2) 系统资源监控并报警函数](#(2) 系统资源监控并报警函数)

[2. 函数变量的作用范围](#2. 函数变量的作用范围)

[3. 函数的参数](#3. 函数的参数)

[4. 递归函数](#4. 递归函数)

[二. shell 数组](#二. shell 数组)

[(1) 获取数组长度](#(1) 获取数组长度)

[(2) 读取某下标赋值](#(2) 读取某下标赋值)

[(3) 数组遍历](#(3) 数组遍历)

[(4) 数组切片](#(4) 数组切片)

[(5) 数组替换](#(5) 数组替换)

[(6) 数组删除](#(6) 数组删除)

[三. shell 脚本调试](#三. shell 脚本调试)


函数,则是 shell 脚本中组织代码、提高复用性的关键所在。通过将一系列指令封装成函数,我们可以避免编写大量重复代码,使脚本更在 shell 脚本的编写过程中,调试与测试同样不可忽视。合理的调试策略与工具,如 echo 命令和 bash 的调试参数,能够帮助我们快速定位并解决问题,确保脚本的稳健运行。加简洁、清晰。函数的定义与调用简洁明了

循环语句与函数是 shell 编程中的两大核心要素。它们不仅能够简化脚本的编写过程,还能提升脚本的执行效率和可维护性。

一. shell 函数

1. 函数的用法

Shell 函数可用于存放一系列的指令。在 Shell 脚本执行的过程中,函数被置于内存中,每次调用函数时不需要从硬盘读取,因此运行的速度比较快。在 Shell 编程中函数并非是必须的元素,但使用函数可以对程序进行更好的组织。将一些相对独立的代码变成函数,可以提高程序可读性与重用性,避免编写大量重复代码。

Shell 函数定义的方法

复制代码
[function] 函数名() {
    命令序列
[return x]
}

|---------------------------------------------------------------|
| "function"关键字表示定义一个函数,可以省略; |
| "{"符号表示函数执行命令的入口,该符号可以与函数名同行也可以在函数名下一行的句首; |
| "}"符号表示函数体结束,两个大括号之间{}是函数体; |
| "命令序列"部分可以是任意的 Shell 命令,也可以调用其他函数: |
| "return"表示退出函数返回一个退出值,通过返回值判断执行是否成功,也可以使用 exit 终止整个 Shell 脚本。 |

Shell 函数调用的方法为:函数名〔参数 1] [参数 2]。下面通过具体的示例学习函数的定义与调

用。

(1) 两个数求和

使用 shell 脚本实现两个数相加求和,通过定义函数的方式来完成。sum 函数内部通过 read 命令接收用户分别输入的两个数,然后做加法运算,最后通过调用函数的方式来输出两个数的和。

(2) 系统资源监控并报警函数

该函数会定期监控系统的 CPU 和内存使用率,当使用率超过设定的值时,会发送报警信息,这里简单模拟为输出到控制台,实际应用中可扩展为发送邮件、短信等。

  • 参数说明:函数接收三个参数,分别是CPU使用率值、内存使用率值以及监控间隔时间(秒)
  • 循环监控:使用 while true 循环不断监控系统资源。通过 top 和 free 命令获取 CPU 和内存使用率,使用 bc 命令进行浮点数比较。
  • 报警处理:当使用率超过阀值时,调用 send alert 函数发送报警信息。

2. 函数变量的作用范围

在 she11 脚本中函数的执行并不会开启一个新的子 shell,而是仅在当前定义的 shell 环境中有效。如果 Shell脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。

在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令 local 来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。local 命令的使用如下所示。

上述脚本中,myfun 函数内部使用了 1ocal 命令设置变量 i,其作用是将变量 i 限定在函数内部。myfun 函数外部同样定义了变量 i,内部变量 i 和全局变量 i 互不影响。脚本执行时先调用了函数myfun,函数内部变量 i为 8,所以输出结果是 8。调用完函数之后,给变量i 赋值为 9,再打印外部变量 i,所以又输出 9。

3. 函数的参数

函数的参数的用法

复制代码
函数名称 參数 1 参数 2 参数 3.....

在使用函数参数时,函数名称在前参数在后,函数名和参数之间用空格分隔,可以有多个参数,参数使用1、2、3...的方式表示。以此类推,从第 10 个参数开始,调用方法为{10},不加大括号无法调用成功。下面是函数参数的一个简单应用。

上述脚本接收两个参数,第一个参数是写日志的目标文件,第二个参数是日志信息,整个脚本实现将日志信息写入目标文件内的目的。

4. 递归函数

Shell 也可以实现递归函数,就是可以调用自己本身的函数。在 Linux 系统上编写 shell 脚本的时候,经常需要递归遍历系统的目录,列出目录下的文件和目录,逐层递归列出,并对这些层级关系进行展示。

二. shell 数组

在 shell 脚本中,数组是一种常见的数据结构,主要的应用场景包括:获取数组长度、获取元素长度、遍历元素、元素切片、元素替换、元素删除等等。shell 中的数组与 Java、C、Python 不同,只有一维数组,没有二维数组。数组元素的大小与限制,也不需要事先定义。shell 数组用括号()来表示,元素用空格分隔,元素的下标与大部分编程语言类似从0开始。

数组常用定义方法

复制代码
方法一:
数组名 = (value0 value1 value2...)
方法二:
数组名 = ([0]=value [1]=value [2]=value ...)
方法三:
列表名="value0 value1 value2 ..." 数组名=($列表名)
方法四:
数组名[0]="value" 数组名[1]="value" 数组名[2]="value"
......

(1) 获取数组长度

在 Shell 编程中,数组是一种用于存储多个值的数据结构。获取数组长度(即数组中元素的个数)在很多场景下都非常有用,比如进行数组遍历、数据处理等。普通数组是 shell 中最常见的数组类型,其下标是从 0 开始的连续整数。获取普通数组长度可以使用 {#数组名\[@\]} 或 {#数组名[*]} 这两种语法,它们的效果是一样的。

(2) 读取某下标赋值

在 shell 编程里,你可以读取数组中指定下标的元素,也可以给指定下标的数组元素赋值。普通数组是 shell 中最常用的数组类型,其下标是从0开始的整数。

显示的是第三个元素 数字1代表0,2代表1,依次类推

(3) 数组遍历

在 Shell 编程里,数组遍历指的是按顺序访问数组中的每一个元素,并对这些元素执行特定操作的过程。这在处理一组相关数据时非常有用,比如批量处理文件、统计数据等。

(4) 数组切片

数组切片是一种操作,用于从数组中提取出一部分连续的元素,形成一个新的数组。这个操作在很多编程语言中都有支持,不过不同语言实现数组切片的语法和方式会有所差异。在 Bash 脚本里,也可以进行数组切片操作。语法是 ${array[@]:start:length},其中 start 是开始的索引,length 是要提取的元素个数。

输出整个数组

${数组名[@或*]:起始位置:长度}

将数组切片之后,返回的是字符串,以空格作为分隔符

(5) 数组替换

${数组名[@或*]/查找字符/替换字符}

并不会替换数组中原有的内容

要实现改变原有的数组,可以通过重新赋值实现

(6) 数组删除

删除数组

删除 第三个元素

三. shell 脚本调试

在 shell 脚本开发中,经常碰到一些规范方面的问题,例如忘了使用引号或在 if 语句末尾处忘记加 fi 结束。要注意把复杂的脚本简单化,要思路清晰,并且分段实现。当执行脚本时出现错误后,不要只看那些提示的错误行,而是要观察整个相关的代码段。

为避免编写的脚本出错,除了在编写脚本时注意书写规范,排除语法错误,更重要的是利用调试脚本工具来调试脚本。echo 命令是最有用的调试脚本工具之一,一般在可能出现问题的脚本中加入 echo 命令,采用的是分段排查的方式。

除了 echo 命令之外,bash shell 也有相应参数可以调试脚本。使用 bash 命令参数调试,命令的语法为:

复制代码
sh [-nvx] 脚本名

常用参数的具体含义

|----|---------------------------------------------------|
| -n | 不会执行该脚本,仅查询脚本语法是否有问题,如果没有语法问题就不显示任何内容,如果有问题会提示报错。 |
| -v | 在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也会给出错误提示。 |
| -x | 将执行的脚本内容输出到屏幕上,这个是对调试很有用的参数。 |

当脚本文件较长时,可以使用 set 命令指定调试一段脚本。

相关推荐
长流小哥33 分钟前
Linux 深入浅出信号量:从线程到进程的同步与互斥实战指南
linux·c语言·开发语言·bash
随猿Fa1 小时前
用密钥方式让通过JumpServer代理的服务器可以在我本地电脑直接访问
运维·服务器
派阿喵搞电子1 小时前
Ubuntu 常用命令行指令
linux·ubuntu
库库林_沙琪马2 小时前
Linux 命令全解析:从零开始掌握 Linux 命令行
linux·运维·服务器
嘿rasa2 小时前
2025最新系统 Linux 教程(二)
linux·运维·服务器
浪淘沙jkp2 小时前
AI大模型学习十:‌Ubuntu 22.04.5 调整根目录大小,解决根目录磁盘不够问题
linux·学习·ubuntu
啊吧怪不啊吧2 小时前
Linux常见指令介绍上(入门级)
linux·运维·服务器
菜狗想要变强2 小时前
RVOS-7.实现抢占式多任务
linux·c语言·驱动开发·单片机·嵌入式硬件·risc-v
网络之路Blog2 小时前
【实战中提升自己】 防火墙完结篇之VPX部署–IPSEC VPX,包括与L2TP共存问题
服务器·网络·网络之路一天·华为华三数通基础·华为华三网络基础·数通基础·华为华三数通
ALex_zry3 小时前
从源码到实战:深度解析`rsync`增量同步机制与高级应用
linux·网络·运维开发