5第五章:shell编程实战
shell脚本的构建思路:
1、确定脚本的功能
2、通过功能来思考这个功能的相关方法(找到关键命令)
3、直接将关键命令累加写入到脚本中,然后思考是否会出现特殊情况干扰脚本的执行
4、针对特殊情况,选择合适的流程控制语句,进行脚本功能的丰富
5、对写完的脚本进行测试,根据测试的反馈结果进行脚本的优化
6、整个脚本全部完成后,可以对相应的命令语句进行中文注释,方便以后的查看
命令补充:
tee:配合echo命令可以即回显信息,又可以将echo内容追加到文本中
选项:-a:表示追加,不加-a则表示覆盖
如:echo “今天天气真好” |tee a /root/1.txt
可以查看到CPU使用量的相关命令:
mpstat:注意mpstat统计的是开机到现在的平均值
用法:mpstat 【-P {cpu核心编号或者ALL}】 【显示间隔时间】 【显示次数】
如:mpstat -P ALL 1 3
vmstat
sar
top
可以查看到内存使用量的相关命令:
free:默认以kb为单位显示内存使用量信息
常用选项:
-m:以mb为单位显示
-g:以gb为单位显示
-k:以kb为单位显示
vmstat
可以查看IO的相关系统监控命令:
iostat
iotop:需要单独安装
shell中小数的判断方法:
第一种:可以使用bc计算器进行小数的判断
例:
echo “1.2 > 2.1”|bc
如果返回结果为1,表示比较的结果为正确,如果返回的结果为0,则表示比较的结果错误
第二种:利用awk命令进行比较
例:
awk ‘BEGIN{if(1.2>2.1) {print “0”} else {print “1”}}’
表示,如果比较结果正确则打印0,否则打印1
实际案例脚本
(1)登录欢迎脚本
脚本思路:
通过ps -e命令获取全部进程,通过wc -l统计进程的数量。
因为ps命令会显示一行开头,同时在行尾会显示ps这个进程,所以我们应该将统计的结果减去2,这样就计算出了以打开的进程的真实数量
who可以显示以登陆的用户,通过wc进行统计可以得出登陆的用户的数量
通过who我们可以得到登录到主机的用户的用户名,通过awk取其第一列,并且排序去重,得出用户的名称
通过df -Th可以查看到根目录占用磁盘的百分比,通过awk取倒数第二行的值
将每条命名定义成变量
最终实现的效果就是上图的效果
(2)端口扫描脚本
脚本思路:
我们可以通过ping不同的主机,配合arp命令获取到IP对应主机的MAC地址
通过单独显示第一列和第三列我们就得到了IP地址和MAC地址,然后我们可以将它输出到/etc/ethers文件中
通过-s判断/etc/ethers文件是否为空,非真时为空,同时如果没有该文件,判断出来的结果也会是空文件
通过判断文件是否为空来执行下面的命令。不为空时,检测根下是否有备份目录,没有的话就创建,然后将/etc/ethers文件移动到bak目录中,并以时间为后缀,方便管理员的管理
我们可以调出/etc下ethers文件中的第一列,通过文件中的IP来进行端口的扫描
因为我的arp缓存表中第一例,有不是IP地址的内容
这里我们就可以通过正则表达式过滤IP地址,因为正则表达式中{n,}有\所以我们需要使用–posix来不使用\
我们可以将其定义成一个变量
使用wget来检测ftp是否开启,其中-t是重试次数,-T是超时时间,这里需要设置一下,不然等待时间会很久
最后书写完成的脚本内容
如果你想即echo显示又想增加到文本中可以后面增加个tee
tee -a相当于追加,不加-a相当于替换
最后测试脚本
(3)监控脚本
通过输出top我们可以的到CPU的使用率
通过提取第三行的id那一列的值CPU空闲容量,于100做运算得出的结果便是CPU的使用量,到时候我们可以去和80去比大小来实现报警
通过free -m得到内存的使用情况,-m表示以mb的方式显示内存信息,用awk去除Mem行中total列的值以及free的值,用total减去free的结果除以total乘以100即可得出内存的使用百分比,total代表总内存量,free表示剩余的内存量
因为df -Th可以直接显示出使用量
我们可以以多个空格和%号作为列的分隔符,并指定显示/号的行,世界显示倒数第二行获取该值
我们将实验的命令定义成变量
最后编写好的脚本内容
因为[ ]中无法计算小数,我们可以使用ehco 回显变量及报警值,然后使用bc进行比大小计算,当大于时会回显1,小于时会回显0,所以我们判断如果比对结果等于1就执行报警,同时你也可以将报警使用tee -a追加到文件中,实现即回显又追加到文本,方便管理员查看
同时我们回显的时候可以加上时间,这样我们就知道是什么时候报警的
(1)登录欢迎脚本
#!/bin/bash
PS=$(echo
(
(
((
(((ps -e | wc -l)-2)))
UN=
(
w
h
o
∣
w
c
−
l
)
U
S
=
(who |wc -l) US=
(who∣wc−l)US=(echo -n $(who |awk -F “[ ]+” '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲' |sort |uniq))…(df -Th |awk -F “[ %]+” '$NF=="/" {print KaTeX parse error: Expected 'EOF', got '}' at position 7: (NF-1)}̲') echo "当前系统运行…{PS}个"
echo “当前登录的用户数量为:
U
N
个
"
e
c
h
o
"
当
前
系
统
中
登
录
的
用
户
名
:
{UN}个" echo "当前系统中登录的用户名:
UN个"echo"当前系统中登录的用户名:{US}”
echo “当前系统的根分区磁盘使用率为:${DF}个”
(2)端口扫描脚本
#!/bin/bash
for i in {10…15}
do
ping -c 1 -i 0.1 -w 1 192.168.40.KaTeX parse error: Expected 'EOF', got '&' at position 3: i &̲> /dev/null don…(date +%F-%T)
arp |sed ‘1d’ |awk -F “[ ]+” ‘{print $1"\t"$3}’ >> /etc/ethers
else
arp |sed ‘1d’ |awk -F “[ ]+” '{print $1"\t"KaTeX parse error: Expected 'EOF', got '}' at position 2: 3}̲' >> /etc/ether…(awk --posix ‘/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/ {print $1}’ /etc/ethers)
for a in
A
d
o
w
g
e
t
−
t
1
−
T
1
f
t
p
:
/
/
A do wget -t 1 -T 1 ftp://
Adowget−t1−T1ftp://a &> /dev/null
if [
?
−
e
q
0
]
t
h
e
n
e
c
h
o
"
? -eq 0 ] then echo "
?−eq0]thenecho"{a}主机开启了ftp服务"
else
echo “${a}主机未开启ftp服务”
fi
done
(3)监控脚本
#!/bin/bash
while :
do
CPU=$(top -b -n 1|awk -F “[ ,]+” 'NR3 {print 100-KaTeX parse error: Expected 'EOF', got '}' at position 2: 8}̲') FREE=(free -m |awk 'NR2 {print int (($2-$4)/KaTeX parse error: Expected 'EOF', got '}' at position 7: 2*100)}̲') DF=(df -Th |awk -F “[ %]+” ‘$NF=="/" {print $(NF-1)}’)
if [
(
e
c
h
o
"
(echo "
(echo"CPU > 80" |bc) -eq 1 ]
then
echo “当前CPU使用率超过80%,为$CPU%”
fi
if [
(
e
c
h
o
"
(echo "
(echo"DF > 90" |bc) -eq 1 ]
then
echo “当前磁盘使用率超过90%,为$DF%”
fi
if [
(
e
c
h
o
"
(echo "
(echo"FREE > 90" |bc) -eq 1 ]
then
echo “当前内存使用率超过90%,为$FREE%”
fi
sleep 5
done