【脚本12】批量更改文件名
需求:
找到/123目录下所有后缀名为.txt的文件
批量修改.txt为.txt.bak
把所有.bak文件打包压缩为123.tar.gz
批量还原文件的名字,即把增加的.bak再删除
代码:
#!/bin/bash
now=`date +%F_%T`
mkdir /tmp/123_$now
for txt in `ls /123/*.txt`
do
mv $txt $txt.bak
for f in $txt
do
cp $txt.bak /tmp/123_$now
done
done
cd /tmp/
tar czf 123.tar.gz 123_$now/
for txt in `ls /123/*.txt.bak`
do
name=`echo $txt |awk -F '.' '{OFS="."} {print $1,$2}'`
mv $txt $name
done
【脚本13】监控80端口
需求:
写一个脚本,判断本机的80端口(假如服务为httpd)是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务,并发邮件通知你自己。脚本写好后,可以每一分钟执行一次,也可以写一个死循环的脚本,30s检测一次。
发邮件的脚本参考【脚本11】的示例代码。
代码:
#!/bin/bash
email="user@example.com"
if netstat -lntp |grep ':80' |grep 'httpd'
then
echo "80 port no problem"
exit
else
/usr/local/apache2.4/bin/apachectl restart
python mail.py $email "check_80port" "The 80 port is down."
n=`ps aux |grep httpd|grep -cv grep`
if [ $n -eq 0 ]
then
/usr/local/apache2/bin/apachectl start 2>/tmp/apache_start.err
fi
if [ -s /tmp/apache_start.err ]
then
python mail.py $mail 'apache_start_error' `cat /tmp/apache_start.err`
fi
fi
【脚本14】备份数据库
需求:
设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月。
假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为192.168.123.30,远程提供了一个rsync服务,备份的地址是 192.168.123.30::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。
脚本代码:
#!/bin/bash
PATH=$PATHi:/usr/local/mysql/bin
week=`date +%w`
today=`date +d`
passwd="123456"
backdir="/data/mysql"
r_backupIP="192.168.123.30::backup"
exec 1>/var/log/mysqlbak.log 2>/var/log/mysqlbak.log
echo "mysql backup begin at `date +%F %T`."
# 本地备份
mysqldump -uroot -p$passwd --default-character-set=utf8 discuz >$backdir/$week.sql
# 同步备份到远程机器
rsync -az $backdir/$week.sql $r_backupIP/$today.sql
echo "mysql backup end at `date +%F %T`."
然后加入cron
0 3 * * * /bin/bash /usr/local/sbin/mysqlbak.sh
【脚本15】自动重启php-fpm服务
服务器上跑的是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
脚本代码:
#!/bin/bash
access_log="/data/log/access.log"
N=10
while :
do
# 因为10秒大概产生300条日志记录
tail -n300 $access_log > /tmp/log
# 拿出log中包含502的日志行数
n_502=`grep -c "502" /tmp/log`
# 如果行数大于10
if [ $n_502 -ge $N ]
then
# 就记录一下系统状态
top -bn1 > /tmp/`date +%H%M%S`-top.log
vmstat 1 5 > /tmp/`date +%H%M%S`-vm.log
# 然后才重启服务,并把错误信息重定向
/etc/init.d/php-fpm restart 2> /dev/null
# 重启php-fpm服务后,应先暂缓1分钟,而后继续每隔10s检测一次
sleep(60)
fi
sleep(10)
done
【脚本16】文本替换
将memcached里的数据导出到文件中,然后再导入memcached里却发现数据过期了,这是因为导出的数据是带有一个时间戳的,这个时间戳就是该条数据过期的时间点,如果当前时间已经超过该时间戳,那么是导入不进去的。不过可以修改文件中的时间戳来保证导入时数据的有效期。可以写一个简单的脚本批量替换这些文件中的时间戳:
#!/bin/bash
hour=`date -d "+1 hour" +%s` # 一个小时之后的时间戳
data_time=`cat data.txt |grep add |awk '{print $4}' |sort -n |uniq`
for i in $data_time
do
sed -i "s/$i/$hour/g" `grep $i -rl /root/data.txt`
done
【脚本17】启动容器
docker每次关闭都会连带着将运行中的容器关闭,所以每次启动docker后都需要逐个去启动容器,很麻烦,由于是实验用的虚拟机不是线上的机器,所以就直接写了一个很简单的循环来启动容器:
#!/bin/bash
/usr/bin/systemctl start docker
for i in `docker ps -a |grep 'Exited' |awk '{print $1}'`
do
/usr/bin/docker start $i
done
【脚本18】删除文本中的字母
要求:把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。
参考答案:假设文本名字叫做1.txt,并且文本行数大于10,脚本如下:
#!/bin/bash
## 先获取该文本的行数
rows=`wc -l 1.txt |awk '{print $1}'`
## 对前5行进行处理
for i in `seq 1 5`
do
## 使用sed把每一行的内容赋值给变量
row=`sed -n "$i"p 1.txt`
## 用grep 判定是否匹配字母,-v取反,-q不输出内容
if echo $row |grep -vq '[a-zA-Z]'
then
echo $row
fi
done
## 对6-10行做删除字母处理
for i in `seq 6 10`
do
row=`sed -n "$i"p 1.txt`
echo $row |sed 's/[a-zA-Z]//g'
done
## 剩余的直接输出
for i in `seq 11 $rows`
do
sed -n "$i"p 1.txt
done
##若想把更改内容写入到1.txt,还需要把以上内容重定向到一个文本中,然后删除1.txt,再把刚刚重定向的文件更名为1.txt
【脚本19】查找字母数小于6的单词
用shell打印下面这句话中字母数小于6的单词。
Bash also interprets a number of multi-character options.
- 脚本如下:
#!/bin/bash
for s in Bash also interprets a number of multi-character options
do
n=`echo $s |wc -c`
if [ $n -lt 6 ]
then
echo $s
fi
done
【脚本20】输入数字执行对应命令
写一个脚本实现如下功能: 输入一个数字,然后运行对应的一个命令。显示命令如下:
cmd meau* 1—date 2–ls 3–who 4–pwd
当输入1时,会运行date, 输入2时运行ls, 依此类推。
实现脚本如下:
#!/bin/bash
echo "*cmd meau** 1—date 2–ls 3–who 4–pwd"
read -p "please input a number 1-4: " n
case $n in
1)
date
;;
2)
ls
;;
3)
who
;;
4)
pwd
;;
*)
echo "Please input a number: 1-4"
;;
esac
【脚本21】批量创建用户并设置密码
用shell脚本实现如下需求:
添加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。
- 提示:
随机密码使用命令 mkpasswd
在脚本中给用户设置密码,可以使用echo 然后管道passwd命令
实现脚本如下:
#!/bin/bash
for i in `seq 00 09`
do
useradd user_$i
p=`mkpasswd -s 0 -l 10`
echo "user_$i $p" >> /tmp/user0_9.pw
echo $p |passwd -stdin user_$i
done
#【脚本22】监控httpd进程
在服务器上,写一个监控脚本。
每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
若没有正常启动还需再一次启动,最大不成功数超过5次则需要理解发邮件通知管理员,并且以后不需要再检测!
如果启动成功后,1分钟后再次检测httpd进程数,若正常则重复之前操作(每隔10s检测一次),若还是大于等于500,那放弃重启并需要发邮件给管理员,然后自动退出该脚本。假设其中发邮件脚本为mail.py
- 实现脚本如下:
#!/bin/bash
check_service(){
n=0
for i in seq 1 5
do
# apachectl命令所在路径
/usr/local/apache2/bin/apachectl restart 2> /tmp/apache.err
if [$? -ne 0 ]
then
n=$[$n-1]
else
break
fi
done
if [ $n -eq 5 ]
then
## mail.py的内容参考https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
python mail.py “123@qq.com“ “httpd service down” cat /tmp/apache.err
exit
fi
}
while :
do
t_n=ps -C httpd --no-heading |wc -l
if [ $t_n -ge 500 ]
then
/usr/local/apache2/bin/apachectl restart
if [ $? -ne 0 ]
then
check_service
fi
sleep 60
t_n=ps -C httpd --no-heading |wc -l
if [ $t_n -ge 500]
then
python mail.py “123@qq.com“ “httpd service somth wrong” “the httpd process is budy.”
exit
fi
fi
sleep 10
done
# 【脚本23】封ip
- 需求:
根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!
- 分析:
我们要做的,不仅是要找到哪些ip请求量不合法,并且还要每隔一段时间把之前封掉的ip(若不再继续请求了)给解封。 所以该脚本的关键点在于定一个合适的时间段和阈值。
比如, 我们可以每一分钟去查看一下日志,把上一分钟的日志给过滤出来分析,并且只要请求的ip数量超过100次那么就直接封掉。 而解封的时间又规定为每半小时分析一次,把几乎没有请求量的ip给解封!
- 参考日志文件片段:
157.55.39.107 [20/Mar/2015:00:01:24 +0800] www.aminglinux.com “/bbs/thread-5622-3-1.html” 200 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
61.240.150.37 [20/Mar/2015:00:01:34 +0800] www.aminglinux.com “/bbs/search.php?mod=forum&srchtxt=LNMP&formhash=8f0c7da9&searchsubmit=true&source=hotsearch” 200 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
- 脚本实现如下:
``` bash
#!/bin/bash
## 日志文件路径
log_file="/home/logs/client/access.log"
## 当前时间减一分钟的时间
d1=`date -d "-1 minute" +%H:%M`
## 当前时间的分钟段
d2=`date +%M`
## iptables命令所在的路径
ipt="/sbin/iptables"
## 用于存储访问日志里的ip
ips="/tmp/ips.txt"
## 封ip
block(){
## 把日志文件中的ip过滤出来,去掉重复的ip,并统计ip的重复次数以及对ip进行排序,最后将结果写到一个文件中
grep "$d1:" $log_file |awk '{print $1}' |sort -n |uniq -c |sort -n > $ips
## 将文件里重复次数大于100的ip迭代出来
for ip in `awk '$1 > 100 {print $2}' $ips`
do
## 通过防火墙规则对这些ip进行封禁
$ipt -I INPUT -p -tcp --dport 80 -s $ip -j REJECT
## 将已经封禁的ip输出到一个文件里存储
echo "`date +%F-%T` $ip" >> /tmp/badip.txt
done
}
## 解封ip
unblock(){
## 将流量小于15的规则索引过滤出来
for i in `$ipt -nvL --line-number |grep '0.0.0.0/0' |awk '$2 < 15 {print $1}' |sort -nr`
do
## 通过索引来删除规则
$ipt -D INPUT $i
done
## 清空规则中的数据包计算器和字节计数器
$ipt -Z
}
## 为整点或30分钟就是过了半个小时,就需要再进行分析
if [ $d2 == "00" ] || [ $d2 == "30" ]
then
unblock
block
else
block
fi
【脚本24】部署前端项目
最近做了一个web前端的项目,需要编写一个脚本完成项目的上线。
- 脚本实现如下:
#!/bin/bash
#
# 使用方法:
# mmall:front_deploy.sh mmall-fe
# admin:front_deploy.sh admin-fe
#
GIT_HOME=/developer/git-repository/ # 从git仓库拉取下来的源码的存放路径
DEST_PATH=/product/frontend/ # 项目打包后的发布路径
# cd dir
if [ ! -n "$1" ]
then
echo -e "请输入要发布的项目!"
exit
fi
if [ $1 = "mmall-fe" ]
then
echo -e "===========Enter mall-fe============="
cd $GIT_HOME$1
elif [ $1 = "admin-fe" ]
then
echo -e "===========Enter mall-fe============="
cd $GIT_HOME$1
else
echo -e "输入的项目名没有找到!"
exit
fi
# clear git dist
echo -e "===========Clear Git Dist============="
rm -rf ./dist
# git操作
echo -e "===========git checkout master============="
git checkout master
echo -e "===========git pull============="
git pull
# npm install
echo -e "===========npm install============="
npm install --registry=https://registry.npm.taobao.org
# npm run dist
echo -e "===========npm run dist============="
npm run dist
if [ -d "./dist" ]
then
# backup dest
echo -e "===========dest backup============="
mv $DEST_PATH$1/dist $DEST_PATH$1/dist.bak
# copy
echo -e "===========copy============="
cp -R ./dist $DEST_PATH$1
# echo result
echo -e "===========Deploy Success============="
else
echo -e "===========Deploy Error============="
fi