作用: shell 函数就是用来解决代码的重复使用问题
1. 什么是函数?
Shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为Shell函数。给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能。
2.函数的基本用法
函数名(){
函数体
}
或
function 函数名(){
函数体
}
注: 函数只有在被调用之后才会执行
函数调用
#!/bin/bash
# 定义函数方式1:
getMax(){
a=1
b=2
if [ $a -gt $b ];then
echo $a
else
echo $b
fi
}
getMax
# 定义函数方式2:
function getMin(){
a=1
b=2
if [ $a -lt $b ];then
echo $a
else
echo $b
fi
}
getMin
定义格式:
-
函数名(){}
-
function 函数名(){}
提问:函数名称一般建议是怎么样的格式:小驼峰或者蛇皮走位
大驼峰,小驼峰,蛇皮走位(user_name)
大驼峰:每个单词的首字母都是大写
小驼峰:如果是多个单词,那么首个单词的首字母是小写,其他的单词的首字母是大写
蛇皮命名法(下划线命名法):没有大写,全部是小写,只不过每个单词之间使用下划线来分割
大驼峰一般是用来定义类的,或者给文件起名的
3.函数传参实现
注意: 在shell脚本中,函数自身并没有任何参数,所谓函数都是通过$1 $2 $3 等内置变量实现
案例: 编写一个函数,用于计算两个数的和
shell中的函数的小括号内,不写任何东西,传参全部靠使用 $1,$2这种方式来获取
vi getMax.sh
#!/bin/bash
getMax(){
num1=$1
num2=$2
}
getMax $1 $2
如何传递参数:
bash getMax.sh 10 20
代码实现:
#!/bin/bash
getMax(){
num1=$1
num2=$2
if [ $num1 -gt $num2 ];then
echo $num2
else
echo $num2
fi
}
getMax $1 $2
调用时: bash xxx.sh 10 20
4.函数的return返回值
作用: 在shell脚本中,return 语句的作用是从函数中退出并返回一个退出状态码,通常用于指示函数的执行结果成功或者失败
注意: 函数的返回值是用$?来获取
基本语法:
# 调用函数
func
# 获取函数的返回值
echo $?
注意:
1.如果你有return,后面必须跟的是0-255的值,不能跟其他内容,因为返回值是一个状态码,我们需要根据状态码来确定你的函数的执行成功与否
2. retuen可以作为函数的结束,相当于是循环中的break
3.如果返回值是0,代码函数执行成功,如果是非0,代表函数执行失败(函数体中的代码有 错误)
4.如果我的函数中没有写return,那么返回值是你的函数体的最后一行代码
-
案例: 定期检查磁盘使用率并告警
某公司需要确保其生产环境中的服务器磁盘空间不会耗尽,以免影响系统的正常运行。运维团队希望使用 Shell 脚本定期检查服务器磁盘使用情况,当某个磁盘分区的使用率超过设定的阈值时,自动发出告警信息(例如通过发送邮件或日志记录),以便运维团队及时处理。
项目需求:
-
定期检查服务器上各个分区的磁盘使用情况。
-
设定一个使用率的阈值(如 80%),当某个分区的使用率超过此阈值时发出告警。
-
在告警时记录日志,并发送邮件给运维团队,提醒需要清理磁盘。
-
使用 Shell 函数实现各项功能,包括检查磁盘、记录日志和发送告警。check_disk_usage()、alert_disk_usage()
解决方案:使用 Shell 函数进行磁盘检查和告警
Shell 脚本思路:
-
编写一个 Shell 函数来检查所有分区的磁盘使用率。
-
编写另一个函数来记录告警信息并发送邮件通知。
-
将这个脚本设为定时任务,通过
crontab
每隔一段时间执行。
提前安装sendmail邮件服务
yum install sendmail
systemctl start sendmail
systemctl enable sendmail
注意:如果电脑中安装了sendmail,但是还是无法发送邮件,本质问题在于你的主机名称不符合FQDN规范。
例如:
node1.itcast.cn
普及一个概念
df -h |grep '^/dev/' | while read line
do
echo $line
done
实现原理:就是前面命令执行结果传递给while + read line,while是一个循环,前面命令返回多少行,则循环会自动循环多少次。read line相当于从前面命令中读取每一行信息
while + read line,就是把前面命令的每一行读取到line这个变量中,$line就相当于前面命名返回的每一行信息
除此以外,read line在读取过程中,如果发现前面返回结果中列与列之间如果包含多个空格,则会自动进行压缩,只保留1个空格,这对我们进行cut截取非常方便!
注意:line如果要cut切割,必须是echo进行赋值变量
#!/bin/bash
# 需求:
# - 定期检查服务器上各个分区的磁盘使用情况。
# - 设定一个使用率的阈值(如 80%),当某个分区的使用率超过此阈值时发出告警。
# - 在告警时记录日志,并发送邮件给运维团队,提醒需要清理磁盘。
# - 使用 Shell 函数实现各项功能,包括检查磁盘、记录日志和发送告警。
# check_disk_usage()、alert_disk_usage()
# 定义一个日志文件用来存储 告警情况
log_file=disk_log_sendmail.log
# 定义一个阈值
threshold=20
# 定义了一个发送邮件的 邮箱
email_from=Centos9@itcast.cn
# 定义了一个接收邮件的 邮箱
email_to=你的邮箱
# 1.先定义函数
# 邮件告警
alert_disk_usage(){
# 1.先拿到你传递的两个参数
partition=$1
disk_usage=$2
# 2.该发送邮件告警了
echo "$(date +%F-%T) $partition 磁盘使用率已经达到 $disk_usage"
{
# 1.谁发的邮件
echo "From: $email_from"
# 2.谁收的邮件
echo "To: $email_to"
# 3.邮件主题
echo "Subject: 磁盘使用率已经达到 $disk_usage%"
# 4.中文乱码处理
echo "MIME-Version: 1.0"
echo "Content-Type: text/html; charset=UTF-8"
echo "Content-Transfer-Encoding: 8bit"
# 5.输出一个空格,目的:和上述的内容分开
echo ""
# 6.发送邮件内容
echo "【$(date +%F-%T)】 $partition 磁盘使用率已经达到 $disk_usage%,请检查分区使用情况!"
}|sendmail -t
}
# 磁盘检查
check_disk_usage(){
# 读取到的就是 /, /boot的情况
df -h | grep '^/dev/' | while read line; # 特点:会将你的多空格时,变成1个空格
do
# line就是每个分区的情况
# 只要在函数内部定义的变量,都是局部变量,出了函数,就失效了
partition=$(echo $line | cut -d ' ' -f1)
disk_usage=$(echo $line | tr -s ' '|cut -d ' ' -f5 | tr -d '%')
# 判断是否超过阈值
if [ $disk_usage -ge $threshold ]; then
echo "磁盘 $partition 使用率已经超过 $threshold%,超过阈值了" >> /var/log/disk_usage.log
alert_disk_usage $partition $disk_usage
fi
done
}
check_disk_usage