一:函数的用法
Shell函数可用于存放一系列的指令。在Shell脚本执行的过程中,函数被置于内存中,每次调用函数时不需要从硬盘读取,因此运行速度比较快。在Shell编程中函数并非是必要元素,但使用函数可以对程序进行更好的组织。将一些相对独立的代码变成函数,可以提高程序可读性与重用性,避免编写大量重复代码
Shell函数定义的方法如下:
[ function ] 函数名() {
命令序列
[ return x ]
}
a.“function”关键字表示定义一个函数,可以省略;
b.“{”符号表示函数执行命令的入口,该符号可以与函数名同行也可以在函数名下一行的句首;
c.“}”符号表示函数体结束,两个大括号之间{ }是函数体
d.“命令序列”部分可以是任意的Shell命令,也可以调用其他函数;
e.“return”表示退出函数返回一个退出值,通过返回值判断执行是否成功,也可以使用exit终止整个Shell脚本。
Shell函数调用的方法为:函数名 [ 参数 1 ] [ 参数 2 ]
(1)两个数求和
通过定义函数的方式来完成。sum函数内部通过read命令接受用户反别输入的两个数,然后做加法运算,最后通过调用函数的方式来输出两个数的和。
命令:vim sum.sh
#!/bin/bash
sum() { (定义sum函数)
echo "请输入第一个数" (提示用户输入第一个数)
read num1
if ! [[ $num1 =~ ^[0-9]+$ ]]; then (检查是否输入有效数字)
echo "输入的第一个数不是有效的整数,请重新运行脚本并输入正确的数>字"
return 1
fi
echo "请输入第二个数"
read num2
if ! [[ $num2 =~ ^[0-9]+$ ]]; then
echo "输入的第二个数不是有效整数,请重新运行脚本并输入正确数字"
return 1
fi
result=$((num1+num2)) (计算两数之和)
echo "两数之和为:$result"
}
sum (调用sum函数)
chmod +x sum.sh
./sum.sh
(2)系统资源监控并报警函数
该函数会定期监控系统的CPU和内存使用率,当使用率超过设定的阈值时,会发送报警信息,这里简单模拟为输出到控制台,实际应用中可扩展为发送邮件、短信等
命令:vim jiankong.sh
#!/bin/bash
send_alert() { (发送报警信息的函数)
local message=$1
echo "ALERT: $message"
} (这里可以添加发送邮件、短信等报警逻辑)
monitor_system_resources() { (系统资源监控函数)
local cpu_threshold=$1
local mem_threshold=$2
local interval=$3
while true; do
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}')(获取CPU使用率)
mem_usage=$(free | awk '/Mem/ {printf("%.2f",$3/$2 * 100)}') (获取内存使用率)
if (( $(echo "$cpu_usage > $cpu_threshold" | bc -l) ) ); then
send_alert "CPU usage ($cpu_usage%)."
fi
if (( $(echo "$mem_usage > $mem_threshold" | bc -l) ) ); then
send_alert "Memory usage ($mem_usage%)."
fi
sleep "$interval"
done
}
monitor_system_resources 8 1 5 (调用函数)
参数说明:函数接受三个参数,反别是CPU使用率阈值、内存使用率阈值、监控间隔时间(秒)
循环监控:使用while true循环不断监控系统资源。通过top和free命令获取COU和内存使用率,使用bc命令进行浮点数比较。
报警处理:当使用率超过阈值时,调用send_alert函数发送报警信息
2:函数变量的作用范围
在Shell脚本中函数的执行并不会开启一个新的子Shell,而是仅在当前定义的Shell环境中有效。如果Shell脚本中的变量没有经过特殊设置,默认在整个脚本中都有效的。
在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令local来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。local命令的使用如下;
命令:vim fun_scope.sh
myfun ()
{
local i
i=8
echo $i
}
i=9
myfun
echo $i
chmod +x fun_scope.sh
./fun_scope.sh
上述脚本中,myfun函数内部使用了local命令设置变量i,其作用是将变量i限定在函数内部。myfun函数外部同样定义了变量i,内部变量i和全局变量i互不影响。脚本执行时先调用了函数myfun,函数内部变量i为8,所以输出结果是8.调用完函数之后,给变量i赋值为9,再打印外部变量i,所以又输出9.
3:函数的参数
函数的参数的用法如下:
函数名称 参数1 参数2 参数3.....
在使用函数参数时,函数名称在前参数在后,函数名和参数之间用空格分隔,可以有多个参数,参数使用$1、$2、$3......的方式表示。以此类推,从第10个参数开始,调用方法为${10},不加大括号调用成功。
命令:vim write_log.sh
#!/bin/bash
mydir="/data" outfile="${mydir}/my.log"
[ -e "${mydir}" ] | | mkdir -p ${mydir}
appendfile()
{
echo "$2" >> "$1"
}
appendfile ${outfile} "first line contnet."
appendfile ${outfile} "second line contnet."
chmod +x write_log.sh
./write_log.sh
cat /data/my.log
上述脚本接受两个参数,第一个参数是写日志文件,第二个参数是日志信息,整个脚本实现将日志信息写入目标文件内的目的
4:递归函数
Shell也可以实现递归函数,就是可以调用自己本身的函数。在Linux系统上编写She11 脚本的时候,经常需要递归遍历系统的目录,列出目录下的文件和目录,逐层递归列出,并对这些层级关系进行展示。具体的实现过程如下所示。
命令:vim fun recursion.sh
#!/bin/bash
traverse_ directory() { (定义递归遍历目录的函数)
local dir=$1
for item in "$dir"/*; do (遍历当前目录下的所有文件和文件夹)
if [ -d "$item" ]; then
echo "Directory: $item" ( 如果是目录,递归调用函数继续遍历 )
traverse_ directory "$item"
elif [ -f "$item" ]; then
echo "File: $item" (如果是文件,输出文件路径)
fi
done
}
traverse_directory ",” ( 调用函数,从当前目录开始遍历)
chmod x fun_recursion.sh
./fun_recursion.sh
函数list.files的第一个参数是列表的目录表,第二个参数是调整的空间
二:Shell数组
在Shell 脚本中,数组是一种常见的数据结构,主要的应用场景包括:获取数组长度、获取元素长度、遍历元素、元素切片、元素替换、元素删除等等。Shell 中的数组与 Java、C、Python 不同,只有-维数组,没有二维数组。数组元素的大小与限制,也不需要事先定义。shell数组用括号()来表示元素用空格分隔,元素的下标与大部分编程语言类似从8开始。
数组常用定义方法包括以下几种:
方法一:
数组名=(value0 value1 value2...)
方法二:
数组名=([0]=value [1]=value [2]=value ...)
方法三:
列表名=“value0 value1 value2...”数组名=($列表名)
方法四:
数组名[0]=“value” 数组名[1]=” value” 数组名[2]=“value”
....
(1)获取数组长度
在 Shell编程中,数组是一种用于存储多个值的数据结构。获取数组长度(即数组中元素的个数在很多场景下都非常有用,比如进行数组遍历、数据处理等。普通数组是Shellaf 中最常见的数组类型其下标是从开始的连续整数。获取普通数组长度可以使用${#数组名[@]}或 ${#数组名[*]}这两种语法,它们的效果是一样的。
命令:arr_number=(1 2 3 4 5)
arr_length=${#arrr_number[*]}
echo $arr_length
arr_length_1=$(#arr_number[@])
echo arr_length_1
(2)读取某下标赋值
Shell编程里,可以读取数组中指定下的元素,也可以给指定下标的数组元素赋值。普通数组是Shell中最常用的数组类型,其下标是从0开始的整数
命令:arr_index2=${arr_number[2]} (显示第三个元素)
echo $arr_index2
3
(3)数组遍历
Shell编程里,数组遍历指的是按顺序访问数组中的每一个元素,并对这些元素执行特定操作的过程
命令:vim arr_traverse.sh
#!/bin/bash
arr_number=(1 2 3 4 5)
for v in ${arr_number[@]}
do
echo $v
done
chmod +x array_traverse.sh
./array_traverse.sh
(4)数组切片
数组切片是一种操作,用于从数组中提取出一部分连续的元素,形成一个新的数组。这个操作在很多编程语言中都有支持,不过不同语言实现数组切片的语法和方式会有所差异。在Bash脚本里,也可以进行数组切片操作。语法是${array[@]:start:length),其中start是开始的索引,length 是要提取的元素个数。
命令:arr=(1 2 3 4 5)
echo ${arr[@]}
echo ${arr[@]:0:2} (:起始位置:长度)
(5)数组替换
命令:arr=(1 2 3 4 5)
echo ${arr[@/4/66] } (/查找字符/替换字符)
echo ${arr[@]} (并不会替换数组原有内容)
arr=(${arr[@]/4/66}) (要实现改变原有数组,可通过重新赋值实现)
(6)数组删除
命令:arr=(1 2 3 4 5)
unset arr (删除数组)
echo ${arr[*]}
arr=(1 2 3 4 5)
unset arr[2] (删除第三个元素)