Linux系统入门第十一章 --Shell编程之函数与数组

news2025/5/11 2:14:30

一、Shell函数

1、函数的用法

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

格式:

function() {

代码块
[return x]

}

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

Shel1 函数调用的方法为:函数名「参数 1]〔参数 2]

栗子1:两个数求和

#!/bin/bash
#定义 sum 函数
sum() {
read -p "请输入第一个数字:" A
#检查是否为有效数字
if ! [[ $A =~ ^[0-9]+$  ]]
then
        echo "这不是一个有效数字,请重新输入"
        return 1
fi


read -p "请输入第二个数字:" B
if ! [[ $B =~ ^[0-9]+$  ]]
then
        echo "这不是一个有效数字,请重新输入"
        return 1
fi

#计算两数之和
result=$((A + B))
echo "两数之和是:$result"
}
#调用函数
sum

执行结果:

栗子2:监控系统资源

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

#!/bin/bash
send_alert() {

local message=$1
echo "ALERT:$message"

}


#系统资源控制函数
monitor_system_resources() {

local cpu_threshold=$1
local mem_threshold=$1
local interval=$3


while true
do
#获取CPU的使用率
cpu_usage=$(top -bn1 | grep Cpu | awk '{print $2+$4}')
#获取内存使用率
mem_usage=$(free | grep Mem | awk '{print $3/$2 *100}')

if (($(echo "$cpu_usage > $cpu_threshold" |bc -l)))
then
        send_alert "CUP usage (${cpu_usage}%)"
fi

if (($(echo "$mem_usage > $mem_threshold" |bc -l)))
then
        send_alert "Mem usage (${mem_usage}%)"
fi

sleep "$interval"

done
}
#调用函数
monitor_system_resources 2 5 2

执行结果:

参数说明:函数接收三个参数分别是CPU使用率值内存使用率值以及监控间隔时间(秒)

循环监控:使用 while true 循环不断监控系统资源。通过 top 和 free 命令获取 CPU 和内存使用率,使用 bc 命令进行浮点数比较。

报警处理:当使用率超过阈值时,调用 send alert 函数发送报警信息

2、函数变量的作用范围

在 Shel1 脚本中函数的执行并不会开启一个新的子 Shell,而是仅在当前定义的 shel1 环境中有效。如果 Shel1 脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。
在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令 1ocal 来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。local 命令的使用如下所示。

#!/bin/bash
AAA(){
local i 
i=8     
echo $i
}       
i=9
AAA
echo $i

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

3、递归函数

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

#!/bin/bash
#定义递归遍历目录的函数
traverse_directory() {
local dir=$1
#遍历当前目录下所有的目录和文件
for item in "$dir"/*
do      
        if [ -d "$item"  ]
        then    
#如果是目录则递归调用函数继续循环
                echo "这是目录:$item"
                traverse_directory "$item"
        elif [ -f "$item"  ]
        then    
#如果是文件就输出路径
                echo "这是文件:$item"
        fi      
done    
}
#调用函数
#“.”:当前目录
traverse_directory "."

执行结果:

二、Shell数组

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

fruits=("Apple" "Banana" "Cherry")  # 元素带空格时必须加引号
nums=(10 20 30)                    # 数字类型可不加引号

1、获取数组长度

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

#定义一个数组A
A=(1 2 3 4 5 6)

#打印数组A的长度
#方法一:
echo ${#A[@]}
#方法二:
echo ${#A[*]}

2、读取指定元素对应的值

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

#定义一个数组A
A=(1 2 3 4 5 6)

#读取3号元素对应的值
echo ${A[3]}

#读取数组中所有的元素值
echo ${A[@]
echo ${A[*]

3、数组遍历

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

#!/bin/bash
A=("好" "好" "学" "习" "天" "天" "向" "上")
for i in ${A[@]}
do      
        echo $i
done

执行结果:

4、数组切片

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

#定义一个数组A
A=(1 2 3 4 5 6)

echo ${A[@]}


echo ${A[@]:0:5}


echo ${A[@]:1:5}

5、数组替换

#定义一个数组A
A=(1 2 3 4 5 6)

#打印数组元素对应的值
echo ${A[@]}
#1 2 3 4 5 6

#将4号元素对应的值5修改为100
echo ${A[@]/5/100}

#将4号元素对应的值6修改为200
echo ${A[@]/6/200}

6、数组删除

#定义一个数组A
A=(1 2 3 4 5 6)

#删除数组中的指定的3号元素
unset A[3]

#删除数组
unset ${A[*]}
unset A

三、Shell脚本调试

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

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

除了echo命令之外,bash Shell也有相应参数可以调试脚本

sh [-nvx] 脚本名
-n不会执行该脚本,仅查询脚本语法是否有问题,如果没有语法问题就不显示任何内容,如果有问题会提示报错
-v在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也会给出错误提示
-x

将执行的脚本内容输出到屏幕上,这个是对调试很有用的参数

#!/bin/bash
set -x #开启调试
#定义 sum 函数
sum() {
read -p "请输入第一个数字:" A
#检查是否为有效数字
if ! [[ $A =~ ^[0-9]+$  ]]
then
        echo "这不是一个有效数字,请重新输入"
        return 1
fi


read -p "请输入第二个数字:" B
if ! [[ $B =~ ^[0-9]+$  ]]
then
        echo "这不是一个有效数字,请重新输入"
        return 1
fi
set +x #关闭调试
#计算两数之和
result=$((A + B))
echo "两数之和是:$result"
}
#调用函数
sum

总结:

函数:函数是Shell脚本中组织代码、提高复用性的重要手段。通过将一系列指令封装成函数,可以避免代码重复,使脚本更加简洁易读。函数的定义与调用简单直观,支持参数传递和递归调用,为模块化开发提供了便利。

数组:作为Shell脚本中的一种重要数据结构,数组支持存储多个值,并提供了丰富的操作方法,如获取数组长度、读取和赋值、遍历、切片、替换和删除元素等。这些功能在处理一组相关数据时非常有用。

调试与测试:在Shell脚本编写过程中,调试与测试是确保脚本正确运行的关键环节。通过使用echo命令和bash的调试参数(-n、-v、-x),可以方便地定位和解决问题,提高脚本的稳健性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聊聊自动化办公未来趋势

1. 自动化办公未来趋势 1.1 智能化与AI融合加深 随着人工智能技术的不断成熟,其在自动化办公中的应用将更加广泛和深入。未来,办公软件将具备更强的智能交互能力,能够理解自然语言指令,自动完成复杂的任务,如文档编辑…

HarmonyOS学习——ArkTS语法介绍之基本知识

ArkTS是一种为构建高性能应用而设计的编程语言。ArkTS在继承TypeScript语法的基础上进行了优化,以提供更高的性能和开发效率。 目前流行的编程语言TypeScript是在JavaScript基础上通过添加类型定义扩展而来的,而ArkTS则是TypeScript的进一步扩展。TypeS…

电子电器架构 --- 网关转发时延解析

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

特殊配合力(SCA)作为全基因组关联分析(GWAS)的表型,其生物学意义和应用价值

生物学意义 解析非加性遗传效应 特殊配合力(SCA)主要反映特定亲本组合的杂交优势,由非加性遗传效应(如显性、超显性、上位性)驱动。显性效应涉及等位基因间的显性互作,上位性效应则涉及不同位点间的基因互作。通过SCA-GWAS,可以定位调控这些非加性效应的关键基因组区域…

2025年 全新 AI 编程工具 Cursor 安装使用教程

一、Cursor 软件下载 首选,登录Cursor官网,进行软件下载,官网下载地址如下: Cursor AI IDE 下载 二、Cursor软件安装配置 此处以Windows10系统安装为例,下载完成之后,右键安装包,以管理员身份…

HarmonyOS 鸿蒙操作物联网设备蓝牙模块、扫描蓝牙、连接蓝牙和蓝牙通信

01【HarmonyOS 蓝牙】 物联网无线传输方案、HarmonyOS蓝牙数据通信之前的准备工作 02【HarmonyOS 蓝牙】配置蓝牙权限 检测 打开 关闭蓝牙 扫描蓝牙 显示蓝牙设备 03【HarmonyOS 蓝牙】连接蓝牙 发现服务 获取特征值 读取信息 写入信息 和蓝牙模块交互 04【物联网 Wifi模块…

【质量管理】TRIZ因果链分析:解码质量问题的“多米诺效应“

为什么要使用因果链分析 没有发现问题并不等于没有问题。爱因斯坦曾说,如果我只有一个小时的时间来拯救世界,我将花45分钟时间分析问题,10分钟的时间来检查问题,最后5分钟的时间来解决问题。可见问题分析的重要性。 在质量管理实践…

解决librechat 前端界面没有google gemini 2.5模型的选项

问题概述 根据librechat 的更新清单,是支持了google gemini的模型,但是却找不到界面上较新的 2.5模型的配置选项。 通过查阅项目的文档(GitHub), 看到: 由于目前还不支持获取模型列表,因此您应…

项目实战-基于信号处理与SVM机器学习的声音情感识别系统

目录 一.背景描述 二.理论部分 三.程序设计 编程思路 流程图 1.信号部分 创建数据 generate_samples.py 头文件 生成函数 generate_emotion_sample 传入参数 存储路径 生成参数 创建基础正弦波信号 调制基础正弦波 对于愤怒可以增加噪声 归一化信号 存储 主函…

【论文笔记】SOTR: Segmenting Objects with Transformers

【题目】:SOTR: Segmenting Objects with Transformers 【引用格式】:Guo R, Niu D, Qu L, et al. Sotr: Segmenting objects with transformers[C]//Proceedings of the IEEE/CVF international conference on computer vision. 2021: 7157-7166. 【网…

23盘古石决赛

一,流量分析 1. 计算流量包文件的SHA256值是?[答案:字母小写][★☆☆☆☆] 答案:2d689add281b477c82b18af8ab857ef5be6badf253db1c1923528dd73b3d61a9 解压出来流量包计算 2. 流量包长度在“640 - 1279”之间的的数据包总共有多少…

LLM量化方法:ZeroQuant、LLM.int8()、SmoothQuant、GPTQ、AWQ

文章目录 TLDR;量化分类量化时机量化粒度ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers细粒度硬件感知量化低成本逐层知识蒸馏(Layer-by-layer Knowledge Distillation, LKD) LLM.int8(): 8-bit Matrix…

【深度学习】【目标检测】【Ultralytics-YOLO系列】YOLOV3核心文件detect.py解读

【深度学习】【目标检测】【Ultralytics-YOLO系列】YOLOV3核心文件detect.py解读 文章目录 【深度学习】【目标检测】【Ultralytics-YOLO系列】YOLOV3核心文件detect.py解读前言if name ‘main’parse_opt函数main函数run函数不同命令参数的推理结果常规推理命令推理命令(新增…

耳机插进电脑只有一边有声音怎么办 解决方法分享

当您沉浸在音乐或电影中时,如果突然发现耳机只有一边有声音,这无疑会破坏您的体验。本文将提供一系列检查和修复方法,帮助您找出并解决问题,让您的耳机恢复正常的立体声效果。 一、检查耳机连接是否正常 首先需要确认耳机与播放设…

Dp通用套路(闫式)

闫式dp分析法: 从集合角度来分析DP问题。 核心思想: DP是一种求有限集中的最值或者个数问题 由于集合中元素的数量都是指数级别的,直接用定义去求,把每种方案都用dfs暴力枚举一遍,时间复杂度很高,此时用…

华为设备端口隔离

端口隔离的理论与配置指南 一、端口隔离的理论 基本概念 端口隔离(Port Isolation)是一种在交换机上实现的安全功能,用于限制同一VLAN内指定端口间的二层通信。被隔离的端口之间无法直接通信,但可通过上行端口访问公共资源&#…

RabbitMq(尚硅谷)

RabbitMq 1.RabbitMq异步调用 2.work模型 3.Fanout交换机(广播模式) 4.Diret交换机(直连) 5.Topic交换机(主题交换机,通过路由匹配) 6.Headers交换机(头交换机) 6…

GAF-CNN-SSA-LSSVM故障诊断/分类预测,附带模型研究报告(Matlab)

GAF-CNN-SSA-LSSVM故障诊断/分类预测,附带模型研究报告(Matlab) 目录 GAF-CNN-SSA-LSSVM故障诊断/分类预测,附带模型研究报告(Matlab)效果一览基本描述程序设计参考资料 效果一览 基本描述 本研究提出的GA…

数据分析怎么做?高效的数据分析方法有哪些?

目录 一、数据分析的对象和目的 (一)数据分析的常见对象 (二)数据分析的目的 二、数据分析怎么做? (一)明确问题 (二)收集数据 (三)清洗和…

stm32之TIM定时中断详解

目录 1.引入1.1 简介1.2 类型1.2.1 基本定时器1.2.2 通用定时器1. 触发控制单元 (Trigger Control Unit)2. 输入捕获单元 (Input Capture Unit)3. 输出比较单元 (Output Compare Unit)4. CNT 计数器5. 自动重装载寄存器 (ARR)6. 预分频器 (PSC)7. 中断与 DMA 事件8. 刹车功能 (…