例6 监测80端口
要求:写一个脚本判断本机80端口(加入服务为httpd)是否开启,如果开启什么都不做,如果端口不存在,那么重启一下httpd服务,并发邮件通知自己,可以每分钟执行一次也可以写死循环脚本,30秒监测一次
要点
监测80端口使用nmap -p 80 127.0.0.1或者netstat -lntp|grep -w ':80'
重启httpd服务的命令要知道
发邮件的脚本依然时候mail.py
nmap -p 80 127.0.0.1 | grep '88/tcp'| awk '{print $2}'
#!/bin/bash
m=123@123.com
while :
do
n=`netstat -lntp | gerp ':80' | wc -l`
if [ $n -eq 0 ]
then
/usr/loacl/apache2/bin/apachectl -k restart 2>/tmp/apache.err
python mail.py $m "80端口关>闭" "已经重启httpd服务"
pn=`pgerp -l httpd|wc -l`
if [ $pn -eq 0 ]
then
python mail.py $m "httpd重启失败" `head -1 /tmp/apache.err`
fi
fi
sleep 30
done
例7 备份数据库
要求:设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月
假设,我们知道mysql root账号密码,要备份的数据库为discuz,本地备份目录为/bak/mysql,远程服务器为192.168.123.30,远程提供一个rsync服务,备份地址是192.168.123.30::backup,写完脚本后,需要加入到cron中,每天凌晨3点执行
要点: 备份数据库命令
同步到远程去的命令
命名规则
#!/bin/bash
d1= `date +%w`
d2= `date +d`
local_bakdir=/bak/mysql
remote_bakdir=192.168.123.30::backup
exec 1> /tmp/mysqlbak.log 2>/tmp/mysqlbak.err
echo "mysql bakcup begin ad `date`"
mysqldump -uroot -pxxxx discz > $local_bkdir/discuz.sql.$d1
rsync -az $local_bakdir/discuz.sql.$d1 $remote_bakdir/discuz.sql.$d2
echo "mysql bakup end at `date`"
例8 监测502
要求:服务器上跑的是lnmp环境,近期总是有502现象,502为网站访问的状态码,200正常,502错误是nginx最为普遍的错误代码。由于502只是暂时的,并且只要一重启php-fpm服务则502小时,一旦发生502,则自动重启一下php-fpm
我们设定
access_log /data/log/access.log
脚本死循环,每10s监测一次(假设每10s的日志条数为300左右)
重启php-fpm的方法是 /etc/init.d/php-fpm restart
要点
用curl监测状态码是否是502或者通过分析日志判断状态码的比率,重启php-fpm服务命令
#!/bin/bash
log=/data/log/access.log
while :
do
502_n=tail -n 300 $log | grep -c ' 502 '
if [ -z "$502_n" ]
then
exit
fi
if [ $502_n -eq 100 ]
then
/etc/init.d/php-fpm restart >/dev/null 2>/tmp/php-fpm.err
fpm_p_n=`pgrep -l|wc -l`
if [ $fpm_p_n -eq 0 ]
then python mail.py xx@xx.com "PHP-fpm重启失败" "`head -1 /tmp/php-fpm.err`"
exit
fi
fi
sleep 10
done
例9 删除字母和行
要求:把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉
要点:sed命令
#!/bin/bash
sed -n '1,5'p 1.txt |sed '/[a-zA-Z]/d'
sed '1,5d' 1.txt |sed '1,5s/[a-zA-Z]//g'
例10 找单词
要求:用shell打印下面这句话中字母数少于6的单词
Bash also interprets a number of multi-character options.
核心
for循环遍历所有单词
wc -L 获取字符串长度
#!/bin/bash
c="Bash also interprets a number of multi-character options."
n= `echo $c | awk -F '[ +-.]' '{print NF}'`
for ((i=1;i<$n;i++))
do
l=`echo $c|awk -F '[ +-. ]' -v j=$i'{print $j} ' | wc -l `
if [ $l -lt 6 ]
then
echo $c |awk -F '[ +-.]' -v j=$i '{print $j}'
fi
done