目录
一. shell 函数
1. 函数的用法
(1) 两个数求和
(2) 系统资源监控并报警函数
2. 函数变量的作用范围
3. 函数的参数
4. 递归函数
二. shell 数组
(1) 获取数组长度
(2) 读取某下标赋值
(3) 数组遍历
(4) 数组切片
(5) 数组替换
(6) 数组删除
三. 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 命令指定调试一段脚本。