当前位置: 首页 > article >正文

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

一、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]+$  ]]
thenecho "这不是一个有效数字,请重新输入"return 1
firead -p "请输入第二个数字:" B
if ! [[ $B =~ ^[0-9]+$  ]]
thenecho "这不是一个有效数字,请重新输入"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=$3while 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)))
thensend_alert "CUP usage (${cpu_usage}%)"
fiif (($(echo "$mem_usage > $mem_threshold" |bc -l)))
thensend_alert "Mem usage (${mem_usage}%)"
fisleep "$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]+$  ]]
thenecho "这不是一个有效数字,请重新输入"return 1
firead -p "请输入第二个数字:" B
if ! [[ $B =~ ^[0-9]+$  ]]
thenecho "这不是一个有效数字,请重新输入"return 1
fi
set +x #关闭调试
#计算两数之和
result=$((A + B))
echo "两数之和是:$result"
}
#调用函数
sum

总结:

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

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

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

相关文章:

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

一、Shell函数 1、函数的用法 Shell函数可用于存放一系列的指令。在Shell脚本执行的过程中,函数被置于内存中,每次调用函数时不需要从硬盘读取,因此运行的速度比较快。在Shell编程中函数并非是必须的元素,但使用函数可以对程序进…...

AWS VPC架构师指南:从零设计企业级云网络隔离方案

一、VPC核心概念解析 1.1 核心组件 VPC:逻辑隔离的虚拟网络,可自定义IPv4/IPv6地址范围(CIDR块) 子网(Subnet): 公有子网:绑定Internet Gateway(IGW)&#…...

聊聊自动化办公未来趋势

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

Flutter 异步原理-Zone

前言 Zone 是 Dart 异步模型中的核心机制,主要用于: 隔离异步上下文,形成逻辑上的执行环境。捕获未处理的异步异常,保证系统稳定。自定义异步任务的调度行为(比如微任务、Timer)。 什么是 Zone&#xff1…...

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

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

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

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

minio数据迁移(两台服务器没法相互通信)

场景描述: A服务器 无法访问 B服务器,B服务器 也无法访问 A(即双方都不能通过公网或内网直连对方) MinIO 官方提供了 mc(MinIO Client)命令行工具,可以直接实现 Bucket 之间的数据迁移: 安装 …...

笔记,麦克风的灵敏度

麦克风的“灵敏度(Sensitivity)”决定了它捕捉声音细节的能力。想象麦克风是一只有耳朵的生物。高灵敏度麦克风像长着“超级顺风耳”的精灵,能听见花瓣飘落的声音、远处树叶的沙沙声,甚至你心跳的微弱震动。适合录音棚里捕捉歌手的…...

特殊配合力(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模块…...

MVC是什么?分别对应SpringBoot哪些层?

作为Java开发者,理解MVC在SpringBoot中的实现方式直接影响我们构建可维护的Web应用能力。本文将用生产级代码示例揭示各层对应关系,并分享分层设计中的实用技巧。 一、MVC本质:解耦的艺术(SpringBoot视角) 1. 经典MVC三元组 组件职责SpringBoot对应层典型代码注解Model数…...

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

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

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

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

STM32实现simpleFOC控制无刷电机

一、FOC基础知识学习 使用simpleFOC控制无刷电机前,需要大概了解一下相关知识,包括力矩控制、速度控制、位置控制的原理和它们之间的联系。 推荐学习资料: 教你写一个比SimpleFOC更好的电机库_哔哩哔哩_bilibili 《灯哥手把手教你写FOC算…...

Redis-数据一致性问题与解决方案

Redis-数据一致性问题与解决方案 引言 Redis 是一个高性能的内存数据库,广泛应用于缓存、会话存储、实时分析等场景。作为一个 NoSQL 数据库,它的高性能和丰富的数据结构使其成为现代微服务架构中不可或缺的组件。然而,在高并发的环境下&am…...

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

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

二、【LLaMA-Factory实战】数据工程全流程:从格式规范到高质量数据集构建

一、引言 在大模型微调中,数据质量直接决定模型性能。LLaMA-Factory提供了完整的数据工程工具链,支持从数据格式规范到清洗增强、注册验证的全流程管理。本文结合结构图、实战代码和生产级经验,带您掌握构建高质量数据集的核心技术。 二、数…...

【论文笔记】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…...

数字经济时代下的消费行为变迁与经济学启示

在信息技术革命的推动下,数字经济正重塑全球经济运行方式。据统计,2022年中国数字经济规模已达50.2万亿元,占GDP比重41.5%。这种结构性变革不仅改变了生产要素配置方式,更深刻重构了微观消费行为模式。本文将从经济学视角分析数字…...

如何阅读GitHub上的深度学习项目

一、前期准备:构建知识基础 1. 必备工具与环境 开发工具: IDE:VS Code(推荐,轻量化插件丰富,如 Python、PyTorch 插件)、PyCharm(适合大型项目)。版本控制:…...

Oracle中自定义异常内置异常嵌套异常的捕获处理

一、异常类型分类 类型说明示例内置预定义异常Oracle已命名异常(如NO_DATA_FOUND)查询无数据时触发内置非预定义异常未命名的Oracle错误(需用PRAGMA EXCEPTION_INIT关联)ORA-02290(违反检查约束)自定义异常…...

【深度学习】【目标检测】【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暴力枚举一遍,时间复杂度很高,此时用…...

ffmpeg录音测试

ffmpeg ffmpeg 是一个强大的多媒体处理工具,可以用于录音、音频处理、视频录制等多种功能。以下是使用 ffmpeg 进行录音的详细指令和参数说明。 基本录音指令 以下是一个简单的 ffmpeg 录音命令,将音频录制为 WAV 格式文件: ffmpeg -f …...

Debezium RelationalSnapshotChangeEventSource详解

Debezium RelationalSnapshotChangeEventSource详解 1. 类的作用与功能 1.1 核心功能 RelationalSnapshotChangeEventSource是Debezium中用于关系型数据库快照的核心抽象类,主要负责: 数据快照:对数据库表进行全量数据快照模式捕获:捕获数据库表结构事务管理:确保快照过…...