SHELL脚本-基础概念(入门级)

SHELL脚本

一、shell概述

1、基本信息

概念:利用Linux命令写成的代码,通过解释器进行运行的程序。

  • /bin/bash:默认解释器
  • cat /etc/shells:查看所有解释器
  • yum -y install ksh:安装新解释器
  • bash的优点:
    • tab键,快捷键,历史记录,管道符,重定向。

2、规范的shell脚本

  • 声明解释器:#!/bin/bash
  • 注释脚本功能,变量含义等
  • 可执行的代码。

3、脚本的运行方式

  • 添加x执行权限
  • 使用解释器执行,开启子进程:bash xxx.sh
  • 使用当前解释器执行,不开启子进程:source xxx.sh
 /dev/null     # 黑洞设备,专用于收集不要的输出信息

 exit 1   # 在shell脚本中,放在一个命令执行后,将此命令定义为错误输出,即$?为非0

二、变量

1、自定义变量

变量名称=值

  • 名称:大小写字母、数字、下划线
    • 不能用特殊字符,不能以数字开头

2、环境变量

  • 系统默认存在的变量
  • USER、UID、HOME、HOSTNAME、 SHELL、PATH、PS1、PS2

3、位置变量

#!/bin/bash

echo $1		#脚本后第1个参数
echo $2		#脚本后第2个参数
echo $3		#脚本后第3个参数
... ...
echo $10	#脚本后第10个参数

4、预定义变量

#!/bin/bash

echo $0			#脚本名
echo $$			#脚本执行时的进程ID号
echo $*			#所有参数
echo $?			#上一条命令是否执行成功
echo $#			#参数的个数

5、查看变量

[root@server ~]# env		#查看所有环境变量
[root@server ~]# set		#查看所有变量

6、扩展知识


  • " " :双引号,界定范围

  • ’ ’ :单引号,界定范围。屏蔽特殊符号

  • `` :反撇号,获取命令执行的结果

  • $():跟反撇号等同,获取命令执行的结果

  • 交互式脚本:read -p “提示信息,自定义” 变量

  • stty -echo:屏蔽回显

  • stty echo :恢复回显

7、变量的发布

[root@ser ~]# export	#发布全局变量
[root@ser ~]# export a=10	#发布新的全局变量
[root@ser ~]# export b		#将局部变量扩展为全局变量
[root@ser ~]# export -n a	#取消全局变量
[root@ser ~]# unset a		#取消变量定义(删除变量)

三、运算

1、expr

#注:数字与运算符号之间要有空格
expr 1 + 1		加
expr 1 - 1		减
expr 2 \* 2		乘
expr 10 / 5		除
expr 10 % 3 	求模,取余数

2、$[] 或 $(())

#无需空格
ehco $[1+1]echo $[1-1]echo [2*2]echo [10/2]echo [10%5]		取余数

3、let

let 用于变量计算。结果不显示
let a=1+1
let b=c+d

变量的自增减:
let a=a-1	相当于	  let a--
let a=a+1	相当于	  let a++
let a=a+2			let a+=2
let a=a-2			let a-=2
let a=a*2			let a*=2
let a=a/2			let a/=2
let a=a%2			let a%=2

4、bc

bc 常用于小数的计算
echo "1.2+3.5" | bc
echo "scale=3;10/3" | bc		#scale定义小数点后显示几位。

四、条件测试

1、字符串

  • ==是否相等
  • != 是否不等
  • -z 是否为空

2、数字

  • -eq:等于;-ne:不等于
  • -lt:小于;-le:小于等于
  • -gt:大于;-ge:大于等于

3、文件

  • -e:存在为真,不管是文件还是目录
  • -f:存在,且是文件才为真
  • -d:存在,且是目录才为真
  • -r:是否有读权限
  • -w:是否有写权限
  • -x:是否有执行权限

4、逻辑测试

  • &&(并且):之前的任务成功,则执行后面的任务
  • || (或者):之前的任务失败,才执行后面的任务

五、判断结构

1、if 判断

# 基本格式

#单分支
if [条件测试];then
	命令
fi

# 双分支
if [条件测试];then
	命令
else
	命令
fi

# 多分支
if [条件测试];then
	命令
elif [条件测试];then
	命令
elif [条件测试];then
	命令
... ...
else
	命令
fi

2、case 分支

  • case分支,相当于简化版本的if,功能 不如if强大,但是代码比较精简。一般用于制作一些小工具。
# 格式:
case 变量 in
模式1)
	命令序列1;;
模式2)
	命令序列2;;
*)
	默认命令序列			# 最后一个可以不用分号。
esac

-----------------------------------------------------------------------
#!/bin/bash
case $1 in
redhat)
        echo "fedora";;
fedora)
        echo "redhat";;
    *)                                              //默认输出脚本用法
    echo "用法: $0 {redhat|fedora}"
esac

六、循环结构

1、for循环

  • 有限的循环,循环的次数和值有关
#基本结构:
for 变量名 in 循环值1、2、3....
do
	命令
done

----------------------------
例1:
#!/bin/bash
for i in {1..10}
do
	echo $i
done
----------------------------
例2:
#!/bin/bash
a=10
for i in `seq $a`	#这里有变量时不能用大括号{}
do
	echo $i
done

2、while循环

  • 无限循环(死循环)
#基本结构:
while 条件测试
do
	命令
done
-------------------------------------------

#!/bin/bash
x=$[RANDOM%100]		#RANDOM:生成随机数。
y=0
while :			#这里':'是指任何条件都成立
do
	let y++
	read -p "猜数(0-99):" n
	if [ $n -gt $x ];then
		echo "大了"
	elif [ $n -lt $x ];then
		echo "小了"
	else
		echo "对了"
		echo "共猜了$y次"
	fi
done

3、循环的控制


  • exit:退出脚本
  • break:终止循环,执行循环之后的任务
  • continue:终止当前循环,继续下一次循环

七、函数

  • 函数一般用在脚本里面,对于一些经常性用到的命令进行一个定义,然后在脚本中可以直接调用。
# 格式1:

function 函数名 {
	命令序列1
	命令序列2
	... ...
}

# 格式2:
函数名 () {
	命令序列
	... ...
}

例:

# 使用函数编写方便调用不同颜色字体的脚本:
#!/bin/bash
cecho (){
echo -e "\033[$1m$2\033[0m"					# 定义了一个函数命令
}
cecho 31 ABCDEFG							# 调用函数命令
cecho 32 ABCDEFG
cecho 33 ABCDEFG
cecho 34 ABCDEFG
cecho 35 ABCDEFG
cecho 36 ABCDEFG
cecho 37 ABCDEFG

# 炸弹脚本
#!/bin/bash
abc(){
abc|abc &
}
abc

八、字符串的处理

1、截取

# 格式:
${变量名:起始位置:长度}		# 起始位置的计算从0开始

# 例:
b=65498165
echo ${b:3:4}		# 截取变量b,从第4位开始截取4位
echo ${b::4}		# 起始为0时可省略0

# 应用:编写随机获取6位密码的脚本
#!/bin/bash
x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
for i in {1..6}
do
	n=${RANDOM%62}
	p=${x:n:1}
	pass=$p$pass
done
echo $pass

2、替换

# 格式:
${变量名/旧/新}

# 例:
b=1802874632
echo ${b/1/a} 		# 将 1 替换为 a
echo ${b/8/a} 		# 将 8 替换为 a
echo ${b//8/a} 		# 将所有 8 替换为 a
echo ${b/0/} 		# 将数字 0 替换为空,相当于删除

3、删除(掐头去尾)

# 格式:
${变量名#*关键词} 			# 从左往右删除 掐头
# 例
a="root:x:0:0:root:/root:/bin/bash"
echo ${a#root} 				# 删除到第一个 root
echo ${a##*root} 			# 删除到最后一个 root,以及此 root 左边所有
echo ${a##*/} 				# 删除到最后一个/,以及此/左边所有
echo ${a#*:root} 			# 删除:root,以及左边所有
-------------------------------------------- 
# 格式
${变量名%关键词*} 			# 从右往左删除 去尾
# 例
echo ${a%bash} 				# 从右往左删除到 bash
echo ${a%root*} 			# 从右往左删除到第一个 root,以及 root 右边所有
echo ${a%/*} 					# 从右往左删除到第一个/,以及/右边所有
echo ${a%%/*} 				# 从右往左删除到最后一个/,以及/右边所有

--------------------------------------------------------------------
# 利用字符串删除功能,编写批量修改文件扩展名的脚本:
#!/bin/bash
for i in `ls *.txt` 首先找到修改目标
do
n=${i%.*} 利用删除中的去尾将扩展名删除,剩下不带扩展名的文件名
mv $i $n.doc 在将上述文件名与.doc 组合,修改为新名字
done

4、初值

# 格式
${变量名:-}

# 例
[root@server0 opt]# a=
[root@server0 opt]# echo ${a:-123}				//当变量是空时调用初值
123
[root@server0 opt]# a=789
[root@server0 opt]# echo ${a:-123}				//变量有值时不使用初值
789
------------------------------------------------------------------------
# 配置密码时使用初值
#!/bin/bash
read -p "请输入用户名:" u
useradd $u
read -p "请输入密码:" p
echo ${p:-123456} | passwd --stdin $u				# 当输入密码为空时,默认密码为123456。

九、正则

1、基本正则

正则符号描述
^匹配行首
$匹配行尾
[ ]集合,匹配集合中的任意单个字符
[^]对集合取反
.匹配任意单个字符
*匹配前一个字符任意次数。不允许单独使用
\ {n,m\ }匹配前一个字符:n 到 m 次
\ {n\ }匹配前一个字符:n 次
\ {n,\ }匹配前一个字符:n 次 及以上
\(\ )保留

2、扩展正则

正则符号描述
+最少匹配一次
?最多匹配一次
{n,m}匹配 n 到 m 次
( )保留,使组合成整体
|或者
\b单词边界

3、grep


  • 配合基本正则
  • 格式为:grep “正则” 文件
# 基本正则的使用:
cat /etc/passwd > user			# 素材
grep ^root user							# 搜索以root开头的
grep in$ user 							# 搜索以in结尾的
grep [in] user							# 搜索字母 i 或者 n
grep [^in] user 						# 搜索除了字母 i 或者 n 以外所有的
grep "."  user							搜索任意单个字符。包括空格,但不包括空行。
grep ".*"  user 						搜索任意。包括空行。
grep "ro*t" user 						# 搜索r?t,r与t之间任意个o

grep "0:\{2\}" user 				# 搜索 0::
grep "\(0:\)\{2\}" user			# 搜索 0:0:

  • 扩展正则
  • grep -E 或 egrep
grep -E "ro+t" user
egrep "ro+t" user

grep -E "bi?n" user
egrep "bi?n" user

grep -E "ro{2,4}t" user			# 搜索ro?t,其中o出现2到4次
grep -E "ro|in" user 				# 搜索ro或in
grep -E "\bthe" user				# 搜索单词the,前面不能有数字字母下划线

grep -E "0:{2}"  user				# 搜索0::
grep -E "(0:){2}"  user 		# 搜索 0:0:

十、Sed

1、格式

流式编辑器。非交互式修改文本,支持正则。

  • 工作方式:逐行处理。
# 使用方式:
sed  选项  '(定址符)/正则/指令'  被处理文件
前置命令 | sed  选项  '(定址符)/正则/指令'

sed 选项  '(定址符)/正则/指令1;(定址符)/正则/指令2;' 文件		# 用分号;隔开多条指令。


# 选项:
-n:屏蔽默认输出
-r:支持扩展正则
-i:写入文件

# 指令:
p:输出
d:删除
s:替换
a:在行下追加
i:在行上追加
c:整行替换

# 定址符,定址符可以不写,不写时,默认逐行处理。
'p'					# 逐行处理。即输出全部
'1p'				# 输出:第1行
'2,5p'			# 输出:第2~5行
'3p;7p'			# 输出:第3行,第7行
'4,+2p'			# 输出:第4行,及后面的2行
'1~2p'			# 输出:奇数行
'2~2p'			# 输出:偶数行
'='					# 显示全部行号
'$='				# 显示最后一行行号

2、基本应用

# 替换
sed 's/xml/abc/'  a.txt				# 将每行中的第1个xml替换成abc 
sed 's/xml/abc/3'  a.txt			# 将每行中的第3个xml替换成abc
sed 's/xml/abc/g'  a.txt			# 将全部xml替换成abc
sed 's/xml//g'	a.txt					# 将全部xml替换成空,即删除

sed 's/\/bin\/bash/\/sbin\/sh/' user		# 将/bin/bash 替换成 /sbin/sh
sed 's#/bin/bash#/sbin/sh'  user
sed 's!/bin/bash!/sbin/sh'  user
sed 's(/bin/bash(/sbin/sh'  user
# 效果与上一条一致。当替换字符中有与替换符冲突时,可以使用数字键上方的任意一种特殊符号代替

------------------------------------------------------------------------
# 正则中保留的特殊使用:()保留,也相当于复制,使用\1\2\3 进行粘贴
sed -r 's/^(.)(.*)(.)$/\3\2\1/' a.tat      # 将每行的第一个字符与最后一个字符对调

表示全部数字[0-9],全部大写字母[A-Z],全部大小写字母[a-Z]

-------------------------------------------------------------------------
# 行下、行上追加,整行替换(在与替换内容之间空格一下)
sed 'a xxxxxx' a.txt				# 所有行下添加
sed '1a xxxxxx' a.txt				# 第1行行下添加
sed '1,2a xxxx' a.txt				# 1~2行下添加
sed 'i xxxxxx' a.txt				# 所有行上添加
sed '2i xxxxx' a.txt				# 第2行上添加
sed 'c xxxxx'  a.txt				# 所有行替换
sed '/abc/c xxxx' a.txt			# 包含abc的行替换成xxxx

3、实际使用

  • 编写脚本,找出使用 bash 的用户,按照 名字 --> 密码 的格式输出
#!/bin/bash
u=`sed -n '/bash$/s/:.*//p' /etc/passwd`			# 找到bash用户,并把名字存入变量b
for i in $u
do
	x=`grep $i:/etc/shadow`
	a1=${x#*:}							# 掐头
	a2=${a1%%:*}						# 去尾
	echo "$i ---> $a2"
done

十一、awk

1、格式


  • awk 数据过滤软件:可以进行精确搜索
  • awk 的默认工作模式:逐行处理。
# 格式:
awk 选项 '条件{指令}' 被处理文件					# 条件和指令需要使用单引号,指令必须用{}
前置命令 | awk 选项 '条件{指令}'

awk 选项 '条件{指令1;指令2;指令3}' 文件    # 多条指令间用分号;隔开


# 常用选项
-F 				# 自定义分隔符。默认情况下,分隔符是空格或tab
-F:				# 以:为分隔符
-F[:/]		# 以:和/ 为分隔符

# 常用指令
print			输出

# 内置变量
$0		所有列
$1		第1列
$2		第2列
... ...
NF		列
NR		行

2、条件的使用


2.1、正则
awk '/正则条件/指令'		# 在使用正则时:要用斜线

# ~ 包含;  !~  不包含;		当内置变量与正则使用时需要用到
awk '$1~/正则/指令‘			# 第1列包含...
awk '$1!~/正则/指令'		# 第1列不包含...

2.2、字符、数值比较
==(等于)!=(不等于)>(大于)<(小于)>=(大于等于)<=(小于等于)

# 不写指令时,默认指令为输出{print}
# 常量必须用双引号""标注。
awk 'NR==2' a.txt							# 输出行数等于2的内容。
awk '$1=="root"{print}'	a.txt			#
awk '$1!="root"' a.txt
awk '$3<5' a.txt				# 输出第3列小于5的行
awk '$3=="5"' a.txt			# 输出第3列的字符等于0的行。

2.3、逻辑符号:&&、||
# 逻辑符号一般配合其它的条件因素进行使用。
awk '$2<10 && $2>5' a.txt
awk '$2<10 || $4>15' a.txt
2.4、计算
seq 100 | awk '$1%7==0 || $1~/7/'				# 列出100以内整数中7的位数,或包含7的数。

awk 'BEGIN{x++;print x}'
awk 'BEGIN{x=8; print x+=2}'
awk 'BEGIN{print 2+3}'
awk 'BEGIN{print 2*3}'
awk 'BEGIN{print 23%8}'

3、工作流程的控制


3.1、if
# if中的条件仍然可以使用正则。
if(条件){命令}
if(条件){命令} else{命令}
if(条件){} else if(条件){}.....


# awk中if是个指令,必须放在{}中,但是可以用空格隔开,awk不关心空格。
awk 选项 '(条件){ if(){} else{} }' 文件
3.2、BEGIN、END
# BEGIN{}任务:只执行一次;{}常规任务:逐行执行;END{}:只执行一次

awk 选项 '(条件) BEGIN{} {} END{}'  文件

# 在awk中,是无视空格的。如果输出需要一定的排版,可以用\t
\t	:制表符。相当于tab键。在输出的时候可以起到一定的排版效果。
awk -F: 'BEGIN{print "User \t UID \t Hone"} {print $1 "\t" $3 "\t" $6} END{print "总计 "NR" 行"}'  /etc/passwd

4、数组


  • 数组:一个可以存多个值的变量。本质上,仍是一个变量。
  • 定义数组:数组名[下标]=元素值
  • 调用数组:数组名[下标]
  • 遍历数组:for(变量 in 数组名){print 数组名[变量]}
  • awk数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号
[root@svr5 ~]# 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

[root@svr5 ~]# awk 'BEGIN{a["hehe"]=11;print a["hehe"]}'
11

遍历数组:
for(变量 in 数组名){print 数组名[变量]}
详解:这里for循环中,是将数组的下标分别赋值给变量,再通过输出数组的格式,逐一输出数组值。
  • 实际应用
# 统计Web访问量
[root@svr5 ~]# awk '{ip[$1]++} \
>  END{for(i in ip) {print ip[i],i }}' /var/log/httpd/access_log
4  127.0.0.1
17 192.168.4.5
13 192.168.4.110
.. ..

# 对访问量排序排名:
[root@svr5 ~]# awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log | sort -nr
17 192.168.4.5
13 192.168.4.110
4 127.0.0.1
.. ..


# 排序命令
sort -r 				# 按数字升序排列
sort -n					# 反序
sort -k					# 指定按第几个字段排序

awk细节注意点


  • 指令中如果输出常量,则需要使用双引号。否则,系统会识别为变量,输出会为空。
  • 但是,在常量中,如果包含了变量,需要输出变量,则需要为变量也加上双引号,以抵消外面的双引效果。
    • END{print “总计 “NR” 行”}
  • 条件和指令需要使用单引号,指令必须用{}

应用案例

1、监控脚本

查看性能数据的命令
[root@svr5 ~]# uptime                            //查看CPU负载
[root@svr5 ~]# ifconfig eth0                    //查看网卡流量
[root@svr5 ~]# free                            //查看内存信息
[root@svr5 ~]# df                                //查看磁盘空间
[root@svr5 ~]# wc -l /etc/passwd                //查看计算机账户数量
[root@svr5 ~]# who |wc -l                        //查看登录账户数量
[root@svr5 ~]# rpm -qa |wc -l                    //查看已安装软件包数量
#!/bin/bash
ip=`ifconfig eth0 | awk '/inet /{print $2}'`
echo "本地IP地址是:"$ip
cpu=`uptime | awk '{print $NF}'`            
#awk中NF为当前行的列数,$NF是最后一列
echo "本机CPU最近15分钟的负载是:"$cpu
net_in=`ifconfig eth0 | awk '/RX p/{print $5}'`
echo "入站网卡流量为:"$net_in
net_out=`ifconfig eth0 | awk '/TX p/{print $5}'`
echo "出站网卡流量为:"$net_out
mem=`free | awk '/Mem/{print $4}'`
echo "内存剩余容量为:"$mem
disk=`df | awk '/\/$/{print $4}'`
echo "根分区剩余容量为:"$disk
user=`cat /etc/passwd |wc -l`
echo "本地账户数量为:"$user
login=`who | wc -l`
echo "当前登陆计算机的账户数量为:"$login
process=`ps aux | wc -l`
echo "当前计算机启动的进程数量为:"$process
soft=`rpm -qa | wc -l`
echo "当前计算机已安装的软件数量为:"$soft

2、安全检测脚本


  • 检测ssh登录日志,如果远程登陆账号名错误3次,则屏蔽远程主机的IP
  • 检测ssh登录日志,如果远程登陆密码错误3次,则屏蔽远程主机的IP
过滤帐户名失败的命令(登陆日志文件为/var/log/secure)
[root@svr5 ~]# awk '/Invalid user/{print $10}' /var/log/secure

过滤密码失败的命令
[root@svr5 ~]# awk '/Failed password/{print $11}' /var/log/secure

#!/bin/bash
awk '/Failed password/{print $11}' /var/log/secure  | awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' | awk '$1>3{print $2}'

awk '/Invalid user/{print $10}' /var/log/secure  | awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' | awk '$1>3{print $2}'

3、sed、awk对同一案例的不同应用


要求:

  • 分析出使用bash作登录Shell的本地用户
  • 列出这些用户的shadow密码记录
  • 按每行“用户名 – 密码记录”保存结果
#/bin/bash
A=$(sed -n '/bash$/s/:.*//p' /etc/passwd)             # 提取符合条件的账号记录
for i in  $A                                          # 遍历账号记录
do
    pass1=$(grep $i /etc/shadow)
    pass2=${pass1#*:}
    pass=${pass2%%:*}
    echo  "$i   --> $pass"
done

#/bin/bash
A=$(awk -F:  '/bash$/{print $1}' /etc/passwd)        # 提取符合条件的账号记录
for i in $A
do
        grep $i /etc/shadow | awk -F: '{print $1,"-->",$2}'                
done

3、监控 web 服务

监控 web 服务是否正常,不低于 3 种监控策略。要求间隔 1 分钟,持续监控。

#!/bin/bash
# . /etc/init.d/functions		# 声明调用此文件中的函数。functions文件内有默认已经定义好的一些函数,如:echo_success、action "" /bin/true 等


url=wwchengbi.cn
Port=80

check_web() {
[ -f /etc/init.d/functions ]&& . /etc/init.d/functions		

if [ "`nc -z $url $Port && echo ok`" = "ok" ];then
#if [ "`echo -e '\n'| telnet $url $Port |grep Connected|wc -l`" = "1" ];then
#if [ "`nmap $url -p $Port |grep open |wc -l`" = "1" ];then
#if [ "`curl -I http://$url 2>/dev/null |head -1 |egrep "200|302|301" |wc -l`" ="1" ];then
#if [ "`curl -I -s -o /dev/null -w '%{http_code}\n' http://$url`" = "200" ];then

action "$url $Port" /bin/true					# 打印指定内容,并提示是[OK]
else
action "$url $Port /bin/false"				# 打印指定内容,并提示是[FAILED]
fi
}

main() {
while true
do
check_web
sleep 1m
done
}

main

4、监控 db 服务

  • 监控 db 服务是否正常,不低于 3 种监控策略。要求间隔 1 分钟,持续监控。
#!bin/bash
Port=3306
user=
pw=
IP=

check_db() {
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
if [ `lsof -i:$Port|wc -l` -gt 1 ];then
#if [ "`netstat -tunlp |grep 3306 |wc -l`" = "1" ];then
#if [ `mysql -u$user  -p$pw -h$IP -P $Port -e "show databases;" |wc -l` -gt 1 ];then

action "MySQL $Port online" /bin/true
else
action "MySQL $Port down" /bin/false
fi
}
main() {
while true
do
check_db
sleep 1s
done
}
main

5、监控 web 站点目录

  • 监控 web 站点目录(/var/html/www)下所有文件是否被恶意篡改(文件内容被改了),如果有就打印改动的文件名(发邮件),定时任务每 3 分钟执行一次(10 分钟时间完成)。
#!/bin/bash
# exec < filename:此命令会将stdin重定向到文件中. 从这句开始, 所有的stdin就都来自于这个文件了, 而不是标准输入(通常都是键盘输入); 这样就提供了一种按行读取文件的方法,并且可以使用sed和/或awk来对每一行进行分析。
# read line:读取上一条标准输出

#find  /var/www/html/ -type f  -exec  md5sum {} \; > /tmp/md5_www.log

check_www () {
md5sum -c /tmp/md5_www.log > /tmp/result_www.log
[ ! -f /tmp/result_www.log ] && echo "/tmp/result_www.log not exist." && exit 2


exec < /tmp/result_www.log
while read line
do
file=`echo $line | awk -F':' '{print $1}'`
result=`echo $line | awk -F':' '{print $NF}'`
#echo $file
#echo $result
#sleep 2s
[ ! $result = "OK" ] && action "$file" /bin/false
done
}

main () {
while true
do
LANG=en																		# 
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
[ ! -f /tmp/md5_www.log ] && echo "/tmp/md5_www.log not exist."&& exit 1
check_www
action "Alii check done." /bin/true
sleep 10s
done
}

main

6、监控 MySQL 主从同步

  • 监控 MySQL 主从同步是否异常,如果异常,则发送短信或者邮件给管理员。
  • 提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟
  • 阶段 1:开发一个守护进程脚本每 30 秒实现检测一次。
  • 阶段 2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。
  • 阶段 3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)
#!/bin/bash

port=3306
error=(1158 1159 1008 1007 1062)
MysqlCmd1="mysql -h192.168.4.52 -uroot -p123456 -e"
MysqlCmd2="mysql -h192.168.4.52 -uroot -p123456 -e 'show slave status\G' | egrep '_Running|Last_Errno|Behind_Master' |awk '{print \$NF}'"

is_run() {
[ `lsof -i:$port |wc -l` -lt 2 ] && {
echo "mysql is stop"
exit 1
	}
}

mysql_status() {
array=(`echo $MysqlCmd2 | bash`)
}

judge_error() {
for i in ${error[*]} 
do
if [ "${array[2]}" == "$i" ];then
${MysqlCmd1} "stop slave;SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;start slave;"
else
echo "mysql is failed,error id is ${array[2]}"
fi
done
}

judge_status() {
mysql_status
echo ${array[*]}
if [ "${array[0]}" == "Yes" -a "${array[1]}" == "Yes" -a "${array[3]}" == "0" ];then
echo "Mysql slave is ok"
else
judge_error  #${array[2]}
fi
}

main() {
while true
do
is_run
judge_status
sleep 3
done
}

main

7、解决DOS攻击

  • 用至少两种方法实现!写一个脚本解决 DOS 攻击生产案例
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值