分支结构
if(条件1){编辑指令1}else if (条件2){编辑指令2}else{编辑指令N}
[root@server0 ~]# cat user #准备素材
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@server0 ~]# awk -F: '{if($3==0){print}}' user #如果第三列是0,则输出该行
root:x:0:0:root:/root:/bin/bash
[root@server0 ~]# awk -F: '{if($3<=2){print "haha"}else{print "heihei"}}' user #如果第三列小于等于2,则输出haha,否则输出heihei
haha
haha
haha
heihei
heihei
双分支练习
统计用户UID,小于10和大于1000的数量
[root@server0 ~]# awk -F: '$3>1000' /etc/passwd | wc -l
2
[root@server0 ~]# awk -F: '$3<10' /etc/passwd | wc -l
9
[root@server0 ~]# awk -F: '$3>=10&&$3<=1000' /etc/passwd | wc -l
29
[root@server0 ~]# awk -F: 'BEGIN{a=0;b=0;c=0}{if($3<10){a++}else if($3>1000){b++}else{c++}}END{print a,b,c}' /etc/passwd
9 2 29 #9为UID小于10的数量,2为UID大于1000的数量,29为UID10到1000的数量
分别统计/etc/passwd文件中登录shell是"/bin/bash",登录shell不是"/bin/bash"的用户个数
[root@server0 ~]# awk -F: '{if($7=="/bin/bash"){a++} else{b++}}END{print a,b}' /etc/passwd
3 37
多分支练习
列出UID小于等于10或者大于1000的数量,并统计总数:
[root@server0~]# awk -F: 'BEGIN{x=0;y=0;z=0}{if($3<=10){x++}else if($3>1000){y++}else{z++}}END{print x,y,z}' /etc/passwd
9 7 15
加上常量显示:
[root@server0~]# awk -F: 'BEGIN{x=0;y=0;z=0}{if($3<=10){x++}else if($3>1000){y++}else{z++}}END{print "UID小于10的数量是"x,"UID大于10的数量是"y,"两者总数是"z}' /etc/passwd
UID小于10的数量是9 UID大于10的数量是7 两者总数是15
数组:能够存储多个不同值的特殊变量
定义数组的格式:数组名[下标]=元素值
下标可以是数字或者字母或者变量
调用数组的格式:数组名[下标]
遍历数组的用法:for(变量 in 数组名){print 数组名[变量]}。
定义数组后配合for循环可以方便的查看数组所有内容,次过程成为遍历数组
下标和值可以不用数字
定义数组a自增1,输出结果:
[root@server0~]# awk 'BEGIN{a[0]++;print a[0]}'
1
定义数组a,for循环数组a,由于数组a只有三个下标所以循环3次并输出下标及对应下标的值:
[root@server0~]# awk 'BEGIN{a[0]=0;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}'
0 0
1 11
2 22
定义数组a,下标分别是1和2,然后输出该数组对应下标的值:
[root@server0~]# awk 'BEGIN{a[1]=100;a[2]=200;print a[1],a[2]}'
100 200
调用数组的顺序:
[root@server0~]# awk 'BEGIN{a[1]=100;a[2]=200;print a[2],a[1]}'
200 100
对定义好的数组做运算:
[root@server0~]# awk 'BEGIN{a[1]=100;a[1]++;print a[1]}'
101
定义数组a,for循环遍历数组下标:
[root@server0~]# awk 'BEGIN{a[1]=100;a[2]=200;for(i in a){print i}}'
1
2
定义数组a,for循环遍历数组a:
[root@server0~]# awk 'BEGIN{a[1]=100;a[2]=200;for(i in a){print i,a[i]}}'
1 100
2 200
定义数组的下标为字母a,需要用""引起来
[root@server0~]# awk 'BEGIN{a["a"]="abc";print a["a"]}'
abc
[root@server0~]# cat abc 以abc作为素材
abc
abc
xyz
opq
xyz
abc
在逐行任务中定义数组a++,for循环遍历数组a,显示下标:
[root@server0~]# awk '{a[$1]++}END{for(i in a){print i}}' abc
opq
abc
xyz
逐行任务,相当于收集数据,然后在END任务中用for循环查看数组的所有内容:
[root@server0~]# awk '{a[$1]++}END{for(i in a){print i,a[i]}}' abc
opq 1
abc 3
xyz 2
以上结果解析:
abc (定义ABC下标) a[abc]=1 (统计次数为1次)
abc (已有ABC下标) a[abc]=2 (统计次数为2次)
xyz (定义xyz下标) a[xyz]=1 (统计次数为1次)
opt (定义opt下标) a[opt]=1 (统计次数为1次)
abc (已有ABC下标) a[abc]=3 (统计次数为3次)
xyz (已有xyz下标) a
[root@server0~]# cat abc 以abc为素材
abc 192.168.0.1
abc 192.168.0.1
xyz 192.168.0.2
opq 192.168.0.3
xyz 192.168.0.2
abc 192.168.0.1
[root@proxy mnt]# awk '{ip[$2]++}END{for(i in ip){print i}}' abc
192.168.0.1
192.168.0.2
192.168.0.3
[root@proxy mnt]# awk '{ip[$2]++}END{for(i in ip){print i,ip[i]}}' abc
192.168.0.1 3
192.168.0.2 2
192.168.0.3 1
结果解析:
abc 192.168.0.1 (定义192.168.0.1为下标) a[192.168.0.1]=1 (统计次数为1次)
abc 192.168.0.1 (已有192.168.0.1下标) a[192.168.0.1]=2 (统计次数为2次)
xyz 192.168.0.2 (定义192.168.0.2为下标) a[192.168.0.2]=1 (统计次数为1次)
opt 192.168.0.3 (定义192.168.0.3为下标) a[192.168.0.3]=1 (统计次数为1次)
abc 192.168.0.1 (已有192.168.0.1下标) a[192.168.0.2]=2 (统计次数为3次)
xyz 192.168.0.2 (已有192.168.0.2下标) a[192.168.0.1]=3 (统计次数为2次)
192.168.0.1下标的总数为3次
192.168.0.2下标的总数为2次
192.168.0.3下标的总数为1次
sort 命令: 将文本文件内容加以排序,sort可针对文本文件的内容,以行为单位来排序。
-b 忽略每行前面开始出的空格字符。
-c 检查文件是否已经按照顺序排序。
-d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
-f 排序时,将小写字母视为大写字母。
-i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
-k 针对指定的列进行排序
-m 将几个排序好的文件进行合并。
-M 将前面3个字母依照月份的缩写进行排序。
-n 依照数值的大小排序。是以数字形式排序
-o <输出文件> 将排序后的结果存入指定的文件。
-r 以相反的顺序来排序。是降序
-t <分隔字符> 指定排序时所用的栏位分隔字符。
使用awk统计Web访问排名:
在分析Web日志文件时,每条访问记录的第一列就是客户机的IP地址,其中会有很多重复的IP地址。因此只用awk提取出这一列是不够的,还需要统计重复记录的数量并且进行排序。
通过awk提取信息时,利用IP地址作为数组下标,每遇到一个重复值就将此数组元素递增1,最终就获得了这个IP地址出现的次数。
下面以server0虚拟机作为web服务端:由真机,另一台虚拟机作为测试机
[root@server0~]# rpm -q httpd
httpd-2.4.6-80.el7.centos.x86_64
[root@server0~]# systemctl restart httpd
[root@server0~]# netstat -nutlp |grep :80
tcp LISTEN 0 128 *:80 *:* users:(("httpd",pid=1037,fd=3),("httpd",pid=1036,fd=3),("httpd",pid=1035,fd=3),("httpd",pid=1034,fd=3),("httpd",pid=1033,fd=3),("httpd",pid=1032,fd=3))
[root@server0~]# cd /var/log/httpd
[root@server0 httpd]# ls ##httpd服务的访问日志
access_log error_log
利用真机,其他虚拟机进行访问
[root@server0~
本案例要求编写脚本,实现计算机各个性能数据监控的功能,具体监控项目要求如下:
1.CPU负载
2.网卡流量
3.内存剩余容量
4.磁盘剩余容量
5.计算机账户数量
6.当前登录账户数量
7.计算机当前开启的进程数量
8.本机已安装的软件包数量
1.查看性能数据的命令
1.CPU负载 : [root@server0~]# uptime (top命令或uptime数量,top命令是交互式的!)
2.网卡流量 : [root@server0~]# ifconfig eth0 (ifconfig筛选接收和发送流量)
3.内存剩余容量 : [root@server0~]# free (free -h命令或者head -2 /proc/meminfo)
4.磁盘剩余容量 : [root@server0~]# df (df -h)
5.计算机账户数量 : [root@server0~]# wc -l /etc/passwd (/etc/passwd或者sed命令或者awk命令)
6.当前登录账户数量 : [root@server0~]# who |wc -l (who命令)
7.计算机当前开启的进程数量 : [root@server0~]# ps aux | wc -l (ps aux)
8.本机已安装的软件包数量 : [root@server0~]# rpm -qa |wc -l (rpm -qa)
2.用awk进行处理1-5
1.[root@proxy mnt]# uptime | awk '{print "CPU的平均负载是"$8 $9 $10}' ##列数请参照实际情况,此为案例
2.[root@proxy mnt]# ifconfig eth0 |awk -F[] '/RX p/{print "eth0的接收流量是"$2}'
2.[root@proxy mnt]# ifconfig eth0 |awk -F[] '/TX p/{print "eth0的接收流量是"$2}'
3.[root@proxy mnt]# free -m | awk '/Mem:/{print "当前主机剩余内存空间"$4"MB"}'
4.[root@proxy mnt]# df -h |awk '/\/$/{print "主机根分区剩余空间是"$4}'
5.[root@proxy mnt]# awk 'END{print "本机账户数量是"NR"个"}' /etc/passwd |wc -l
3.编写脚本
[root@server0 ~]# vim jk.sh
#!/bin/bash
while :
do
uptime | awk '{print "当前主机CPU平均负载是"$NF}'
ifconfig eth0 | awk -F[\(\)] '/Rx p/{print "eth0网卡的接收流量是" $2}'
ifconfig eth0 | awk -F[\(\)] '/Tx p/{print "eth0网卡的发送流量是" $2}'
free -h | awk '/Mem/{print "当前主机内存剩余空间是" $4}'
df -h | awk '/vda1/{print "当前主机根分区剩余空间是" $4}'
awk 'END{print "当前主机用户数量总共是"NR"个"}' /etc/passwd
x=`who | wc -l`
echo "当前主机登录账户的数量是$x 个"
p=`ps aux | wc -l`
echo "当前主机开启的进程数量是$p 个"
n=`rpm -aq | wc -l`
echo "当前主机安装的软件包数量是$n 个"
sleep 2
clear #效果与ctrl+l相同
done
[root@server0 ~]# bash jk.sh
当前主机CPU平均负载是0.06
当前主机内存剩余空间是126M
当前主机根分区剩余空间是7.0G
当前主机用户数量总共是41个
当前主机登录账户的数量是2 个
当前主机开启的进程数量是128 个
当前主机安装的软件包数量是1214 个
编写安全检测脚本
防止远程ssh暴力破解密码,具体监控项目要求如下:
检测ssh登录日志,如果远程登陆账号名错误3次,则屏蔽远程主机的IP
检测ssh登录日志,如果远程登陆密码错误3次,则屏蔽远程主机的IP
1.过滤帐户名失败的命令(登陆日志文件为/var/log/secure)
[root@server0~]# awk '/Invalid user/{print $11}' /var/log/secure ##列出登录失败的账号
[root@server0~]# awk '/Invalid user/{ip[$11]++}END{for(i in ip){print ip[i],i}}' /var/log/secure ##统计次数
2. 过滤密码失败的命令
[root@server0~]# awk '/Failed/{print $11}' /var/log/secure ##列出密码登录失败的账号
[root@server0~]# awk '/Failed/{ip[$11]++}END{for(i in ip){print ip[i],i}}' /var/log/secure ##统计次数
3.编写脚本
root@server0 ~]# vim test.sh
#!/bin/bash
#这是一个防止远程登录失败3次的脚本
u=`awk '/Failed/{ip[$11]++}END{for(i in ip){print ip[i],i}}' /var/log/secure | awk '$1>3{print $2}'`
[ -z "$u" ] || echo "有人尝试登录服务器!相关信息是$u" | mail -s test root
此时可以用其他的虚拟机模拟远程登录失败三次
[root@server0 ~]# bash test.sh #执行脚本
[root@server0 ~]# mail #查看root邮件
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 1 message 1 new
>N 1 root Thu Jan 9 15:53 18/634 "test"
& 1
Message 1:
From [email protected] Thu Jan 9 15:53:55 2020
Return-Path:
X-Original-To: root
Delivered-To: [email protected]
Date: Thu, 09 Jan 2020 15:53:55 +0800
To: [email protected]
Subject: test
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=utf-8
From: [email protected] (root)
Status: R
有人尝试登录服务器!相关信息是172.25.0.10
& q
Held 1 message in /var/spool/mail/root