8一、题目要求 : 监控磁盘php
阿里云的机器,今天收到客服来的电话,说服务器的磁盘io很重。因而登陆到服务器查看,并无发现问题,因此怀疑是间歇性地。正要考虑写个脚本的时候,幸运的抓到了一个线索,形成磁盘io很高的幕后黑手是mysql。此时去show processlist,但未发现有问题的队列。原来只是一瞬间。只好继续来写脚本,思路是,每5s检测一次磁盘io,当发现问题去查询mysql的processlist。java
【核心要点】python
iostat -xd 1 5 ,主要看%util ;-xd :只查看磁盘信息。mysql
#!/bin/bash #这个脚本用来监控磁盘IO #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-12 if ! while iostat &>/dev/null then yum install -y sysstat fi while : do t=`date +%T` iostat -xd 1 5 |grep '^sda'> /tmp/io.log sum=`awk '{sum=sum+$NF} END {print sum}' /tmp/io.log` a=`echo "scale=2;$sum/5"|bc` b=`echo $a|cut -d . -f 1` if [ $b -gt 90 ] then mysql -uroot -pxxxx -e "show processlist" > mysql_$t.log fi sleep 1 done
实例 :linux
查看磁盘的读写速度。%util越大,说明磁盘越忙。ios
查看平均磁盘读写速率git
查看磁盘sda的读写速度,查看最后一列。github
将磁盘sda的读写速度写入到/tmp/io.log。取最后一列使用“$NF”,显示磁盘的读写速度是0.02sql
修改磁盘读写速度,用于测试。shell
6.92除以5,求磁盘平均读写速度。
取一位整数
执行脚本,查看结果
注意 :
yum install -y sysstat #安装查看io的命令软件包
if ! while iostat &>/dev/null #查看iostat有没有安装,若是没有,执行下面的任务。
t=`date +%T` #显示当前系统时间
iostat -xd 1 5 |grep '^sda'> /tmp/io.log #将磁盘sda的读写速度写入到/tmp/io.log。
sum=`awk '{sum=sum+$NF} END {print sum}' /tmp/io.log` #将磁盘sda的读写速度写入到/tmp/io.log。取最后一列使用“$NF”,写入到/tmp/io.log。
a=`echo "scale=2;$sum/5"|bc` #除以5,保留2位数字
b=`echo $a|cut -d . -f 1` #取一位整数
if [ $b -gt 90 ] #查看gt的值是否大于90
mysql -uroot -pxxxx -e "show processlist" > mysql_$t.log #若是当发现问题去查询mysql的processlist。,并写入到mysql_$t.log日志里面
8二、题目要求 : 查看tomcat日志
写一个截取tomcat catalina.out日志的脚本 tomcat实例t1-t4
# find /opt/TOM/ -name catalina.out /opt/TOM/t1/logs/catalina.out /opt/TOM/t3/logs/catalina.out /opt/TOM/t4/logs/catalina.out /opt/TOM/t2/logs/catalina.out
要求:
Oct 29, 2018 01:52:24 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-bio-8080"] Oct 29, 2018 01:52:24 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-bio-8009"] Oct 29, 2018 01:52:24 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 2102 ms
【核心要点】
#!/bin/bash #这个脚本用来查看Tomcat日志 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-12 LANG=en logfile="/opt/TOM/$1/logs/catalina.out" #将当天的英文月、数字日期、数字年做为变量赋值给d_mdy d_mdy=`date "+%b %d, %Y"` #判断参数个数 if [ $# -ne 2 ] && [ $# -ne 3 ] then echo "你提供的参数个数不对,请提供2个或者3个参数。例:sh $0 t1 08:01:00 14:00:00" exit 1 fi #判断第一个参数是否符合要求 if ! echo $1|grep -qE '^t1$|^t2$|^t3$|^t4$' then echo "第一个参数必须是t一、t二、t3或t4" exit 1 fi #判断时间有效性 judge_time() { date -d "$1" +%s &>/dev/null if [ $? -ne 0 ] then echo "你提供的时间$1格式不正确" exit 1 fi } #将24小时制时间转换为12小时 tr_24_12() { date -d "$1" +%r } #判断提供的时间点是否在日志中出现 judge_time_in_log() { if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile then echo "你提供的时间$1在日志$logfile中未曾出现,请换一个时间点" exit 1 fi } #判断第2个参数是否合法 judge_time $2 #判断起始时间点是否出如今日志里 judge_time_in_log $2 #若是提供第3个参数 if [ $# -eq 3 ] then #判断第3个参数是否合法 judge_time $3 #判断起始时间是否早于结束时间 t1=`date -d "$2" +%s` t2=`date -d "$3" +%s` if [ $t2 -lt $t1 ] then echo "你提供的时间$2比$3要晚,应该把早的时间放到前面" exit fi #判断提供的结束时间点是否出如今日志中 judge_time_in_log $3 fi #取起始时间所在行行号 begin_n=`grep -n "$d_mdy $(tr_24_12 $2)" $logfile|head -1|awk -F ':' '{print $1}'` #取结束时间所在行行号,并用sed截取日志内容 if [ $# -eq 3 ] then n=`grep -n "$d_mdy $(tr_24_12 $3)" $logfile|tail -1|awk -F ':' '{print $1}'` #结束日期所在行的下一行才是日志的内容 end_n=$[$n+1] sed -n "$begin_n,$end_n"p $logfile else sed -n "$begin_n,$"p $logfile fi
实例 :
查看系统时间,是否和tomcat日志里面的时间同样。
将24小时时间制转换成12小时时间制,和Tomcat日志的时间格式同样,便于观察。
执行脚本,查看结果
注意 “:
date -d "$1" +%s &>/dev/null #将用户输入的参数,写入到/dev/null 中,-d测试,$1表示用户输入的时间
if [ $# -ne 2 ] && [ $# -ne 3 ] #提供的参数 不是2,也不是3时。提示用户。
if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile #将24小时时间制转换成12小时时间制,grep -p检查时间格式是否是和日志中的同样。
8三、题目要求 : 打印城市名字
写一个脚本让用户输入多个城市的名字(能够是中文),要求很多于5个,而后把这些城市存到一个数组里,最后用for循环把它们打印出来。
【核心要点】
赋值数组 : arry=(1 2 a b c)
打印数组 : echo ${arry[@]}
#!/bin/bash #这个脚本用来打印城市名字 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-12 read -p "输入很多于5个城市的名字,用空格分隔开。" name n=`echo $name|awk '{print NF}'` if [ $n -lt 5 ] then echo "请输入至少5个城市的名字." exit fi city=($name) for i in `seq 0 $[${#city[@]}-1]` do echo ${city[$i]} done
实例 :
打印数组
查看数组的循环,发现是从0开始的。
数组的赋值 ;打印数组的值 ; 统计数组的个数 ;针对个别元素。
执行脚本,查看结果。
注意 :
n=`echo $name|awk '{print NF}'` #名字之间,用空格隔开。
if [ $n -lt 5 ] #$n的值小于5,
for i in `seq 0 $[${#city[@]}-1]` #打印用户输入的城市名,由于数组的循环是从0开始的,因此要减一。
8四、题目要求 : 代码上线
需求背景是: 一个业务,有3台服务器(A,B,C)作负载均衡,因为规模过小目前并未使用专业的自动化运维工具。有新的需求时,开发同事改完代码会把变动上传到其中一台服务器A上。可是其余2台服务器也须要作相同变动。
写一个shell脚本,把A服务器上的变动代码同步到B和C上。 其中,你须要考虑到不须要同步的目录(假若有tmp、upload、logs、caches)
rsync同步
密钥认证或者expect脚本
#!/bin/bash #这个脚本用来代码上线 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-12 dir=/data/wwwroot/www.aaa.com B_IP=1.1.1.1 C_IP=2.2.2.2 rs() { rsync -azP --exclude="logs" \ --exclude="tmp" --exclude="upload" \ --exclude="caches" $dir/ $1:$dir/ } read -p "该脚本将会把本机的$dir下的文件同步到$B_IP和$C_IP上,是否要继续?y|n" c case $c in y|Y) rs B_IP rs C_IP ;; n|N) exit ;; *) echo "你只能输入y或者n." ;; esac
注意 :
dir=/data/wwwroot/www.aaa.com #假如a ,b,c机器的变动代码须要同步的目录都是同样。
rsync -azP --exclude="logs" \
--exclude="tmp" --exclude="upload" \
--exclude="caches" $dir/ $1:$dir/ #把A服务器上的变动代码同步到B和C上,排除的目录tmp、upload、logs、caches。 $dir/ $1:$dir/表示$dir同步到b机器下的$dir目录下,$1是b机器的IP
需求背景:
须要统计网站的并发量,并绘图。 说明: 只须要写出shell脚本便可,不用关心zabbix配置。
假设日志路径 /data/logs/www.aaa.com_access.log
日志格式以下:
112.107.15.12 - [07/Nov/2018:09:59:01 +0800] www.aaa.com "/api/live.php" 200"-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"
【核心要点】
查看日志中1秒内的日志数量,即并发数(每秒请求多少次)
#!/bin/bash #这个脚本用来计算网站并发量 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-12 LANG=en t=`date -d "-1 second" +%d/%b/%Y:%` log=/data/logs/www.aaa.com_access.log tail -1000 $log |grep -c "$t"
实例 :
获取上一秒的时间。%b : 做用是显示月份。
获取上一秒的时间,与日志显示的时间一致。
执行脚本,查看结果
注意 :
t=`date -d "-1 second" +%d/%b/%Y:%` # 求上一秒的日志时间
log=/data/logs/www.aaa.com_access.log #访问日志,经过访问日志,计算网站的并发量
tail -1000 $log |grep -c "$t" #统计最后一千条并发量日志,并截取到日志时间
8六、题目要求 : 关闭服务
在centos6系统里,咱们可使用ntsysv关闭不须要开机启动的服务,固然也可使用chkconfig工具来实现。
写一个shell脚本,用chkconfig工具把不经常使用的服务关闭。脚本须要写成交互式的,须要咱们给它提供关闭的服务名字。
chkconfig --list
#!/bin/bash #这个脚本用来关闭服务 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-14 LANG=en while : do chkconfig --list 2>/dev/null|grep '3:on' |awk '{print $1}' > /tmp/on_sev.txt echo -e "\033[32m系统里开启了这些服务: \033[0m" cat /tmp/on_sev.txt echo read -p "Please select a service from this list: " s if ! grep -qw "$s" /tmp/on_sev.txt then echo -e "\033[31m你提供的服务名并未开启.\033[0m" continue fi chkconfig $s off break done
实例 :
查看服务列表
列出开启的服务,并显示在一列。
给字体添加颜色
执行脚本,查看结果
注意 :
chkconfig --list 2>/dev/null|grep '3:on' |awk '{print $1}' > /tmp/on_sev.txt #列出全部的on服务,
echo -e "\033[32m系统里开启了这些服务: \033[0m" #
if ! grep -qw "$s" /tmp/on_sev.txt #查看$s,是否在/tmp/on_sev.txt ,不存在,就提示用户。
chkconfig $s off #关闭不须要开机启动的$s服务。
8七、题目要求 : 完全关闭tomcat服务
在生产环境中,常常遇到tomcat没法完全关闭,也就是说用tomcat自带shutdown.sh脚本没法将java进程彻底关掉。因此,须要借助shell脚本,将进程杀死,而后再启动。
写一个shell脚本,实现上述功能。完全杀死一个进程的命令是 kill -9 pid。
【核心要点】
kill -9 pid
#!/bin/bash #这个脚本用来完全杀死Tomcat进程 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-14 dir=/usr/local/tomcat/bin/ java_pc() { pgrep java|wc -l } cd $dir ./shutdown.sh count=0 while [ $count -lt 5 ] do n=`java_pc` if [ $n -gt 0 ] then killall java count=$[$count+1] sleep 1 else break fi done n=`java_pc` if [ $n -gt 0 ] then killall -9 java fi n=`java_pc` if [ $n -gt 0 ] then echo "Tomcat没法强制杀死。" exit fi cd $dir ./startup.sh
实例 :
执行脚本,查看结果
注意 :
pgrep java|wc -l #把java方面的服务和进程行数,都统计出来。
while [ $count -lt 5 ] #当他关闭的次数小于5
if [ $n -gt 0 ] #当$n大于0。
8八、题目要求 : 去掉文件名后缀
至少用两种方法,批量把当前目录下面全部文件名后缀为.bak的后缀去掉,好比1.txt.bak去掉后为1.txt
【核心要点】
方法一 :用sed把文件名结尾的.bak去掉
方法二 :awk截取去掉后缀的部分,复制变量
#!/bin/bash #这个脚本用来去掉文件名后缀 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-14 for f in `ls -d ./*.bak ` do # mv $f `echo $f|sed 's/.bak$//'` f1=`echo $f|awk -F '.bak$' '{print $1}' ` mv $f $f1 done
实例 :
查看目录下的.bak的文件
执行脚本,查看结果
脚本生成的1。1
注意 :
for f in `ls -d ./*.bak ` #表示目录下的.bak的文件
mv $f `echo $f|sed 's/.bak$//'` #用sed把文件名结尾的.bak去掉
f1=`echo $f|awk -F '.bak$' '{print $1}' ` #awk截取去掉后缀的部分,复制变量,打印第一行。
写一个shell脚本,查询指定域名的过时时间,并在到期前一周,天天发一封提醒邮件。
【核心要点】
能够在Linux下使用命令“whois域名”,如“whois aplelearn.com” ,来获取该域名的一些信息
#!/bin/bash #这个脚本用来检查域名是否到期 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-14 mail_u=admin@admin.com #当前日期时间戳,用于和域名的到期时间作比较 t1=`date +%s` #检测whois命令是否存在,不存在则安装jwhois包 is_install_whois() { which whois >/dev/null 2>/dev/null if [ $? -ne 0 ] then yum install -y epel-release yum install -y jwhois fi } notify() { #e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1` e_d=`whois $1|grep 'Expiration'|tail -1 |awk '{print $5}' |awk -F 'T' '{print $1}'` #若是e_d的值为空,则过滤关键词'Expiration Time' if [ -z "$e_d" ] then e_d=`whois $1|grep 'Expiration Time'|awk '{print $3}'` fi #将域名过时的日期转化为时间戳 e_t=`date -d "$e_d" +%s` #计算一周一共有多少秒 n=`echo "86400*7"|bc` e_t1=$[$e_t-$n] e_t2=$[$e_t+$n] if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ] then python mail.py $mail_u "Domain $1 will to be expired." "Domain $1 expire date is $e_d." fi if [ $t1 -ge $e_t ] && [ $t1 -lt $e_t2 ] then python mail.py $mail_u "Domain $1 has been expired" "Domain $1 expire date is $e_d." fi } #检测上次运行的whois查询进程是否存在 #若存在,须要杀死进程,以避免影响本次脚本执行 if pgrep whois &>/dev/null then killall -9 whois fi is_install_whois for d in aaa.com bbb.com aaa.cn do notify $d done
实例 :
在输入栏里面输入”whois.chinaz.com“ ,查看某个域名的具体信息。
安装查看域名的whois命令软件包,
安装YUM以后,而后就能够安装了
查看aminglinux.com域名的具体信息。
查询百度的域名的过时时间。
只打印出过时的时间
执行脚本,查看结果
注意 :
which whois >/dev/null 2>/dev/null #检测whois软件包
e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1` #获取域名的过时的详细信息,
e_d=`whois $1|grep 'Expiration'|tail -1 |awk '{print $5}' |awk -F 'T' '{print $1}'` #只打印出过时的时间
e_t1=$[$e_t-$n] #$e_t是过时时间,$n表示一周,$e_t-$n域名过时前的一周
e_t2=$[$e_t+$n] # $e_t+$n域名过时后的一周
if [ $t1 -ge $e_t ] && [ $t1 -lt $e_t2 ] #当前时间大于$e_t 域名的过时时间,而且,时间小于一周
e_d=`whois $1|grep 'Expiration Time'|awk '{print $3}'`
fi #只打印出过时的时间
if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ] #若是当前日期不是大于等于$e_t1的过时前的一周,而且,当前日期小于一周后的时间,表示域名过时时间不到一周了。 不到一周就过时或者过时了不到一周,就发邮件。
90、题目要求 : 自动密钥认证
写一个shell脚本,当咱们执行时,提示要输入对方的ip和root密码,而后能够自动把本机的公钥增长到对方机器上,从而实现密钥认证。
【核心要点】
expect #分发脚本命令
ssh-copy-id #公钥
#!/bin/bash #这个脚本用来自动配置密钥认证 #做者:猿课-阿铭 www.apelearn.com #日期:2018-12-14 read -p "输入一个IP地址: " ip read -p "输入此机器的root密码: " pasd is_install() { if ! rpm -q $1 &>/dev/null then yum installl -y $1 fi } is_install openssh-clients is_install expect if [ ! -f ~/.ssh/id_rsa.pub ] then echo -e "\n" |ssh-keygen -P '' fi cat > key.expect <<EOF #!/usr/bin/expect set host [lindex \$argv 0] set passwd [lindex \$argv 1] spawn ssh-copy-id root@\$host expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "\$passwd\r" } } expect eof EOF chmod a+x key.expect ./key.expect $ip $pasd
实例 :
查看机器是否安装远程登陆的命令软件包和分发脚本的命令 : openssh-clients、expect
远程登陆登陆B机器
查看本机密钥 : cat ~/.ssh/id_rsa.pub,ssh-copy-id root@1.1.1.1把本机的公钥增长到对方机器上,而后输入密码就好了。秘钥拷贝到129机器上拷贝成功,129机器上要拷贝到秘钥的目录 :~/.ssh/authorized_keys
查看本机器上的秘钥
写一个分发脚本1.expect ,使用分发脚本登陆 B机器,而后输入IP地址和密码。
查看公钥
查看秘钥存放的目录
查看生成的秘钥
执行脚本,查看结果
注意 :
if ! rpm -q $1 &>/dev/null #查看命令是否运行openssh-clients、expect,若是没有,就安装。
if [ ! -f ~/.ssh/id_rsa.pub ] #查看本地家目录有没有秘钥id_rsa.pub,若是没有,就生成。
写入一个分发脚本,下面是内容
set host [lindex \$argv 0]
set passwd [lindex \$argv 1]
spawn ssh-copy-id root@\$host
来源 : https://github.com/aminglinux/shell100/blob/master/61.md