目录
1、grep
grep通过正则表达式分析程序
grep, egrep, fgrep - print lines matching a pattern
pattern,模式。其实就是一些条件的组合,用来表达某个意思。主要是一些字符串+数字+特殊符号,组成一个公式。
^、$、|(或者)....,这些叫做元字符,有特殊作用的符号,用来描述其他的字符的字符
# [root@fttsaxf ~]# cat /etc/passwd|egrep "^c|^f"等价与下边那个命令
[root@fttsaxf ~]# cat /etc/passwd|grep -E "^c|^f"
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
fdd:x:1003:1003::/home/fdd:/bin/bash
1.1、grep -i和grep -v
-i,查找时,忽略大小写。
-v,反转差查找,输出与模式不相符的行
[root@fttsaxf rough_book]# cat phone.txt
xiaomi
XIAOMI
huawei
HUAWEI oppo vivo
VIVO
iphone
apple
meizu
kupai
nokia
[root@fttsaxf rough_book]# cat phone.txt | grep -i "xiaomi"
xiaomi
XIAOMI
[root@fttsaxf rough_book]# cat phone.txt | grep -i -n "xiaomi"
1:xiaomi
2:XIAOMI
1.2、grep -o
只显示匹配的内容
[root@fttsaxf rough_book]# cat phone.txt | grep -o xiaomi
xiaomi
1.3、grep -r
-r,查找某个目录下所有的文件,然后去匹配字符串
[root@fttsaxf rough_book]# grep -r "xiaomi" ./ # 递归的将当前目录下所有的文件都进行查找看是否有"xiaomi"字符串;"/"后边加不加"*",都可以
./phone.txt:xiaomi
1.4、"^"和"$"
"^XX",查找以XX开头的字符串
"XX$",查找以XX结尾的字符串
"^XX$",查找为XX的字符串
[root@fttsaxf rough_book]# cat phone.txt|grep "^x"
xiaomi
[root@fttsaxf rough_book]# cat phone.txt|grep "e$"
iphone
apple
[root@fttsaxf rough_book]# cat phone.txt|grep "^iphone$"
iphone
1.5、grep -E或者egrep
-E,支持更加多的元字符,支持扩展正则表达式(regular expression)。正则表达式是由字符串+数字+特殊符号按照正确的规则组合而成的,要来表达某个意思的公式。例如:
^root -->表示以root开头。^元字符,有特殊作用的字符。
基本正则,里边有很多常见的元字符 ^、$ 、[]。
扩展正则:在基本正则的基础上新加了很多的元字符,例如: "|",表示或者。+、{}、?
grep不能识别扩展正则,所以需要用到egrep或者grep -E
[root@fttsaxf rough_book]# cat phone.txt |grep "^xiao|^a"
[root@fttsaxf rough_book]# cat phone.txt |egrep "^xiao|^a"
xiaomi
apple
[root@fttsaxf rough_book]# cat phone.txt |grep -E "^xiao|^a"
xiaomi
apple
1.5.1、^$
表示空行
[root@fttsaxf rough_book]# cat phone.txt
xiaomi
XIAOMI
huawei
HUAWEI oppo vivo
VIVO
iphone
apple
meizu
kupai
#
nokia
[root@fttsaxf rough_book]# cat phone.txt |egrep -n "^#|^$" # 找出空行和注释行
4:
11:#
[root@fttsaxf rough_book]# cat phone.txt |egrep -v "^#|^$" # 找出文章中的有效行
xiaomi
XIAOMI
huawei
HUAWEI oppo vivo
VIVO
iphone
apple
meizu
kupai
nokia
1.6、grep -A、grep -B和grep -C
[root@fttsaxf rough_book]# cat phone.txt |grep -A 2 HUAWEI # 查找出HUAWEI,并且显示出后面2行
HUAWEI oppo vivo
VIVO
iphone
[root@fttsaxf rough_book]# cat phone.txt |egrep -B 2 iphone # 查找出iphone,并且显示出前边2行
HUAWEI oppo vivo
VIVO
iphone
[root@fttsaxf rough_book]# cat phone.txt |egrep -C 2 iphone # 查找出iphone,并显示出前后2行
HUAWEI oppo vivo
VIVO
iphone
apple
meizu
1.7、grep小练习
#第一题:
[root@fttsaxf rough_book]# cp /etc/passwd .
#第二题:
[root@fttsaxf rough_book]# cat passwd |egrep "^ftp|^mail"
#第三题:
[root@fttsaxf rough_book]# cat passwd |egrep -v "^m|^r|^f"
[root@fttsaxf rough_book]# cat passwd |egrep -v "^[rmf]"
[root@fttsaxf rough_book]# cat passwd |egrep "^[^rmf]"
"""
[^rmf] 不是rmf字符
^,在中括号里边表示取反;在外边表示以什么开头
"""
#第四题:
[root@fttsaxf rough_book]# cat passwd | grep "bash$"
#第五题:
[root@fttsaxf rough_book]# cat /etc/login.defs |egrep -v "^#|^$"
#第六题:
[root@fttsaxf rough_book]# cat /var/log/messages|egrep -w "[a-Z]{16}"
[root@fttsaxf rough_book]# cat /var/log/messages|egrep "\<[a-Z]{16}\>"
[root@fttsaxf rough_book]# cat /var/log/messages|egrep "\<[a-Z]{16}\b"
Feb 13 23:08:44 fttsaxf NetworkManager[757]: <info> [1644764924.7576] settings: Loaded settings plugin: NMSKeyfilePlugin (internal)
'''
单词的界定符号
\< 以什么开头
\> 单词以什么结尾
\b 可以单独取代\<或者\>
[root@fttsaxf rough_book]# cat phone.txt |egrep "\<iphone" # 查看单词以"iphone"开头的
iphone
iphone11
iphone13pro
[root@fttsaxf rough_book]# cat phone.txt |egrep "iphone\>" # 查看单词以"iphone"结尾的
iphone
maxiphone
[root@fttsaxf rough_book]# cat phone.txt |egrep "\<iphone\>" ## 查看单词"iphone"
iphone
'''
#第七题:
[root@fttsaxf rough_book]# cat passwd |grep "bash$"|grep "liu"
[root@fttsaxf rough_book]# cat passwd |egrep "liu.*bash"
'''
.*,是正则里表示任意字符的意思
'''
#第八题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep -v "^$|^#"
#第九题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep "[0-9][0-9]"
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep "[0-9]{2}"
'''
a{2},表示花括号前边的a连续出现两次
abc{2},表示花括号前边的c连续出现两次。能够匹配的字符串是"abcc"
[0-9]{2},表示从0到9里可以取2次的数字,随便取,取2次
[0-9]{2,5},表示从0到9里可以取2到5次的数字,随便取,最少取2次,最多取5次
[0-9]{2,},表示从0到9里可以取至少两次的数字
'''
#第十题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep "[^0-Z]"
#第十一题:
[root@fttsaxf rough_book]# cat /etc/ssh/ssh_config |egrep -v "[0-9]"
#第十二题:
'''
IP地址是由四个0~255的数字和"."组成
"\.",表示"."符号
".",在正则里表示任意单个字符
'''
[root@fttsaxf rough_book]# cat /var/log/secure|egrep "[0-9]{,3}\.[0-9]{1,3}"
2、diff
用途:比较两个文件之间的差异,输出结果为两个文件的不同之处。
2.1、查看文件是否被人修改过(有备份文件的前提下)
[root@fttsaxf rough_book]# diff passwd passwd.backup
2,5d1
< 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
# 这里是在passwd中增加了几行。要是输出来之后没有输出,则表示没有修改
[root@fttsaxf rough_book]# diff phone.txt phone.txt.backup
13c13
< iphpne11
---
> iphone11
# md5sum,根据文件里的内容计算出一个固定的值。如果文件修改了,里边的内容发生了变化,计算出来的值就会不一样
[root@fttsaxf rough_book]# md5sum phone.txt # 这里使用了"md5"
6f863f83adf0802cf683d20e03058153 phone.txt
[root@fttsaxf rough_book]# vim phone.txt
[root@fttsaxf rough_book]# md5sum phone.txt
583c051794779cc8aaa0e3b60cf898d3 phone.txt
2.2、diff命令的输出格式
2.2.1、diff -u
[root@fttsaxf rough_book]# diff -u phone.txt phone.txt.backup
--- phone.txt 2022-02-16 14:55:51.675261916 +0800
+++ phone.txt.backup 2022-02-16 14:47:50.202355604 +0800
@@ -1,10 +1,10 @@
xiaomi
XIAOMI
-huwei
+huawei
HUAWEI oppo vivo
VIVO
-ipnone
+iphone
apple
meizu
[root@fttsaxf rough_book]# echo $?
1 # 有区别,返回值为"1"
[root@fttsaxf rough_book]# diff test test.backup
[root@fttsaxf rough_book]# echo $?
0 # 没有区别,返回值为"0"
2.3、文件生成补丁和打补丁
补丁:程序更新了的部分。程序是人编写的,可能含有漏洞,发现漏洞之后,需要编写弥补这个漏洞的程序,也就是补丁
2.3.1、生成补丁
# 将phone和phone_v2的差异重定向到一个文件里,这个文件就是补丁包
[root@fttsaxf rough_book]# diff -u phone phone_v2 >phone.patch # 打补丁
[root@fttsaxf rough_book]# ls
phone phone.patch phone_v2
[root@fttsaxf rough_book]# cat phone.patch
--- phone 2022-02-16 15:11:21.534180101 +0800
+++ phone_v2 2022-02-16 15:17:11.332927027 +0800
@@ -13,3 +13,4 @@
iphone11
iphone13pro
maxiphone
+new-phone:iphone19
2.3.2、打补丁
[root@fttsaxf rough_book]# patch phone <phone.patch # 将补丁加入phone中
patching file phone
[root@fttsaxf rough_book]# diff phone phone_v2 # 对比差异发现没有区别了
3、编写脚本
脚本的shell代码为:
#!/bin/bash
# 编写菜单
menu(){
echo "================================"
echo "1.monitor memory usage"
echo "2.scan LAN"
echo "3.monitor /etc/passwd and /etc/hosts"
echo "4.monitor nginx deamon"
echo "5.exit"
echo "================================"
read -p "请输入你的选择:" option
}
# 系统性能监控
usage(){
>1.txt || touch 1.txt
free -m |tail -n +2|awk '{print $1,$2,$3}' >1.txt # 将进程名、总共内存和已使用内容截取出来放入1.txt中
while read name total used
do
# 计算得到内存使用率情况,因为linux里边的默认的除是地板除
pro=$(printf "%.5f" `echo "scale=5;$used/$total"|bc`)
if (( $( echo "$pro > 0.7"|bc ) == 1 ))
then
echo "$name,这台机器的内存使用为$por,超过了70%,请注意"
else
echo "$name,这台机器的内存使用为$pro,没有超标"
fi
done < 1.txt
: <<EOF # 这里只是一个注释
-gt,表示大于
-lt,表示小于
-eq,表示等于
-ne,表示不等于
-ge,表示大于等于
-le,表示小于等于
(( 9 > 8 )) 等效于 [ 9 -gt 8 ],以此类推
EOF
}
# 局域网扫描工具
scan(){
>ip.txt # ">",重定向,有就清空,没有就新建
echo "下面是正在使用的局域网:" >ip.txt
for ip in 192.168.29.{0..255}
do
(
if ping -c 1 $ip &>/dev/null ;then
echo $ip >>ip.txt
continue
fi
break
)&
done
echo "###################"
echo "全部局域网已经扫描完成"
echo "#################"
total=$(cat ip.txt|wc -l) # 统计ip.txt中有多少行
if (( $total > 1 ));then # 因为我之前输入了一个“下面是正在使用的局域网”,所以就是该文件行数大于1才会有ip地址正在使用
cat ip.txt
else
echo "局域网内没有IP地址在使用"
fi
}
# 监控文件是否被修改
# tamper,做手脚;破坏的意思
tamper(){
while :
do
# 作比较之前要使用cp命令把diff后边第一个文件复制到你要比较的位置,切记不要使用mv!!!!
num_1=$(diff /etc/passwd /root/linux/script/menu/passwd.backup|wc -l )
if (( $num_1 == 0 )) # 统计行数为0的话,就是前一个文件没有被修改。因为后一个文件是前一个文件的备份
then
echo "/etc/passwd 文件没有被修改"
else
echo "/etc/passwd 文件被修改了"
fi
sleep 1
num_2=$(diff /etc/hosts /root/linux/script/menu/hosts.backup|wc -l)
if (( $num_2 == 0 ))
then
echo "/etc/hosts 文件没有被修改"
else
echo "/etc/hosts 文件被修改了"
fi
break
done
}
# 监控nginx进程是否存在,存在或者不存在都给予提醒
process(){
if pidof nginx &>/dev/null;then
echo "nginx进程存在"
else
echo "nginx进程不存在"
fi
}
while :
do
menu
case $option in
1)
echo "现在正在进行系统性能监控"
echo "################"
usage
;;
2)
echo "现在正在进行局域网扫描"
scan
;;
3)
echo "现在正在查看监控文件是否被修改"
echo "################"
tamper
;;
4)
echo "现在正在查看监控nginx进程是否存在"
echo "######################"
process
;;
5)
echo "成功退出"
exit
;;
*)
echo "请您配合输入1-5的数字"
;;
esac
echo
read -p "请敲击"Enter"键继续执行你想要的功能"
clear
done
3.1、编程总结
3.1.1、小数的比较
shell里默认双圆括号"(())"支持整数的运算和比较,但是不支持小数的。python都可以支持的。
[root@fttsaxf menu]# ((9>5))
[root@fttsaxf menu]# echo $?
0
[root@fttsaxf menu]# ((0.1>0.2))
-bash: ((: 0.1>0.2: 语法错误: 无效的算术运算符 (错误符号是 ".1>0.2")
[root@fttsaxf menu]# num=`echo "100.7 > 91.8"|bc` # 这里使用的反引号"`"
[root@fttsaxf menu]# num1=$(echo "100.7 > 91.8"|bc) # 这里使用了"$()",推荐使用这个
[root@fttsaxf menu]# echo $num $num1
1 1
# 以上两种写法都是一样的
# 另外awk也可以实现小数的计算
3.1.2、输出值和返回值
输出值:程序运行的过程中的输出内容
返回值:命令是否执行成功。
函数的返回值:return(退出函数),后面不接数字默认情况下是0
脚本的返回值:exit(退出脚本),后面不接数字默认情况下是0
3.2、shell里的多进程思想
3.2.1、并行和串行
并行:同时执行--》速度快
串行:一个一个的执行,按照顺序 --》速度慢
for循环同时产生254个子进程去ping不同的ip地址;(命令) & 产生子bash进程去执行命令放在后台执行。{命令}&也可以
3.2.2、父进程和子进程的问题
当父进程结束的时候,会给所有的子进程发信号,告诉内核杀死所有的子进程。当父进程的程序执行完毕,但是子进程的程序没有执行完,若没有做修改,当父进程做完,子进程就会被全部杀死。
怎么防止这个问题呢?
可以使用wait命令
注意:wait是要放在for循环外边的
3.3、查看nginx进程是否存在
if 命令
then
命令1
else
命令2
fi
当我们要使用返回值和if结合的时候,我们可以直接把命令放在if后边,当后边命令执行成功(也就是返回值为0)就会执行if第一个命令,要是没有成功就会执行第二个命令
4、小数的运算
bc
4.1、如何使用bc
bc有两种方法可以调用
[root@fttsaxf menu]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
9 + 6
15
quit
[root@fttsaxf menu]# echo "9 + 6.9"|bc
15.9
4.2、小数的比较
-gt,表示大于
-lt,表示小于
-eq,表示等于
-ne,表示不等于
-ge,表示大于等于
-le,表示小于等于
(( 9 > 8 )) 等效于 [ 9 -gt 8 ],以此类推
5、awk
awk命令的完整语法
awk的命令的执行过程:BEGIN和END部分只是执行一次,pattern{commands}中间部分每一行都执行一次
[root@fttsaxf menu]# awk -F ":" 'BEGIN{print "#########start###########" } $3>1000 {print $1,$3,$7 } END {print "#####################end###############"}' /etc/passwd
#########start###########
bagnyou 1001 /bin/bash
bangyou 1002 /bin/bash
fdd 1003 /bin/bash
chenxw 1004 /bin/bash
caohx 1005 /bin/bash
zhangjian 1006 /bin/bash
fzt 1007 /bin/bash
califeng 1008 /bin/bash
cali123 1009 /bin/bash
ysdf 1010 /bin/bash
fja 1011 /bin/bash
dfja 1012 /bin/bash
dfjalsk 1013 /bin/bash
#####################end###############
5.1、awk进行小数计算
[root@fttsaxf menu]# awk 'BEGIN{print 89 + 57}'
146
[root@fttsaxf menu]# awk 'BEGIN{print 89 + 57.5}'
146.5
[root@fttsaxf menu]# awk 'BEGIN{printf "%.2f\n",'$a'/'$b'}'
0.33
# %.2f\n,指定awk计算的精度,小数点的数位为2位
5.2、NR和NF
NR:是awk里表示每行里的行号(number of records),记录的行号,一行就是一条记录
NF:是awk里表示一行有多少个字段数(number of fields)
它们都是awk里的内部变量
[root@fttsaxf menu]# free -m
total used free shared buff/cache available
Mem: 1819 206 1470 9 142 1465
Swap: 2047 0 2047
[root@fttsaxf menu]# free -m |awk 'NR==2{print $3/$2}'
0.113249
[root@fttsaxf menu]# free -m |awk 'NR==2{print $3/$2*100}'
11.3249