分类:shell习题
shell习题-域名到期提醒
写一个shell脚本,查询指定域名的过期时间,并在到期前一周,每天发一封提醒邮件。
思路: 大家可以在linux下使用命令“whois 域名”,如”whois apelearn.com”,来获取该域名的一些信息。
提示: whois命令,需要安装jwhois包
参考答案:
#!/bin/bash t1=`date +%s` is_install_whois() { which whois >/dev/null 2>/dev/null if [ $? -ne 0 ] then yum install -y jwhois fi } notify() { e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1` e_t=`date -d "$e_d" +%s` n=`echo "86400*7"|bc` e_t1=$[$e_t-$n] if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ] then /usr/local/sbin/mail.py aming_test@163.com "Domain $1 will be expire." "Domain $1 expire date is $e_d." fi } is_install_whois notify aminglinux.com
shell习题-取消后缀
至少用两种方法,批量把当前目录下面所有文件名后缀为.bak的后缀去掉,比如1.txt.bak去掉后为1.txt
参考答案:
假设取消的后缀为.bak 方法一: for i in `ls *.bak` do mv $i `echo $i|sed 's/\.bak//g'` done 方法二: for i in `ls *.bak` do newname=`echo $i|awk -F '.bak' '{print $1}'` mv $i $newname done
shell习题-重启tomcat服务
在生产环境中,经常遇到tomcat无法彻底关闭,也就是说用tomcat自带shutdown.sh脚本无法将java进程完全关掉。所以,需要借助shell脚本,将进程杀死,然后再启动。
写一个shell脚本,实现上述功能。彻底杀死一个进程的命令是 kill -9 pid.
参考答案:
说明:以下脚本为猿课同学实际线上跑的shell脚本,考虑的方面比较多,大家可以学一学他的思路 #!/bin/bash ###功能: 重启 tomcat 进程 ###要求:对于tomcat中的某些应用,使用shutdown.sh是无法完全停掉所有服务的 实际操作中都需要kill掉tomcat再重启 ## ### root can not run this script. ## if [ $USER = root ] then echo "root cann't run this script!please run with other user!" exit 1 fi ## ### check the Parameter ## if [[ $# -ne 1 ]] then echo "Usage:$0 tomcatname" exit 1 fi ## ### only one process can run one time ## TMP_FILE_U=/tmp/.tmp.ps.keyword.$USER.956327.txt #echo $TMP_FILE_U KEYWORD1="$0" KEYWORD2="$1" # 使用赋值会多fork出一个进程,所以要先重定向到一个文本,再统计. ps ux |grep "$KEYWORD1"|grep "\<$KEYWORD2\>"|grep -v "grep" > $TMP_FILE_U Pro_count=`cat $TMP_FILE_U |wc -l` if [ $Pro_count -gt 1 ] then echo "An other process already running ,exit now!" exit 1 fi ################################################### # # # begin of the script # # # ################################################### ## ### set the Parameter ## TOM=`echo $1|sed 's#/##g'` TOMCAT_DIRECTORY=~/usr/local/$TOM STARTUP_SCRIPT=$TOMCAT_DIRECTORY/bin/startup.sh TOMCAT_LOG=$TOMCAT_DIRECTORY/logs/catalina.out CONF_FILE=$TOMCAT_DIRECTORY/conf/server.xml TEMPFILE=/tmp/.tmpfile.x.89342.c4r3.tmp ## ### check if the tomcat directory exist ## if [ ! -d "$TOMCAT_DIRECTORY" ] then echo "the tomcat \"$TOM\" not exist.check again!" exit 1 fi ## ### log roteta and delete log one week ago ## rotate_log(){ TIME_FORMART=$(date +%Y%m%d%H%M%S) LOG_DIR=$(dirname $TOMCAT_LOG) mv $TOMCAT_LOG ${TOMCAT_LOG}_${TIME_FORMART} find $LOG_DIR -type f -ctime +7 -exec rm -rf {} \; } ## ### function start the tomcat ## start_tomcat() { #echo start-tomcat-func if [ -x "$STARTUP_SCRIPT" ] then rotate_log $STARTUP_SCRIPT sleep 1 tail -f $TOMCAT_LOG else if [ -e $STARTUP_SCRIPT ] then chmod +x $STARTUP_SCRIPT # echo "permition added!" if [ -x "$STARTUP_SCRIPT" ] then rotate_log $STARTUP_SCRIPT sleep 1 tail -f $TOMCAT_LOG else echo "The script not have excute permision,Couldn't add permision to Script!" exit 1 fi else echo "error,the script \"startup.sh\" not exist!" exit 1 fi fi } ## ### function stop the tomcat ## stop_tomcat() { rm -rf $TEMPFILE ps ux |grep /$TOM/ |grep -v "grep /$TOM/"|grep java > $TEMPFILE Pro_Count=`cat $TEMPFILE|wc -l` PIDS=`cat $TEMPFILE|awk '{print $2}'` rm -rf $TEMPFILE #echo $Pro_Count if [ $Pro_Count -eq 0 ] then echo "The tomcat not running now!" else if [ $Pro_Count -ne 1 ] then echo "The have $Pro_Count process running,killed!" kill -9 `echo $PIDS` WC=`ps aux | grep "/$TOM/" | grep -v "grep /$TOM/" | grep java |wc -l` [ $WC -ne 0 ] && (echo "kill process failed!";exit 1) else echo "Process killed!" kill -9 `echo $PIDS` WC=`ps aux | grep "/$TOM/" | grep -v "grep /$TOM/" | grep java |wc -l` [ $WC -ne 0 ] && (echo "kill process failed!";exit 1) fi fi } ########################### #### #### #### The main script #### #### #### ########################### echo -e "are you sure restart $TOM?(y or n)" read ANS if [ "$ANS"a != ya ] then echo -e "bye! \n" exit 1 fi stop_tomcat echo "start tomcat ..." sleep 2 start_tomcat # end
shell习题-关闭服务
在centos6系统里,我们可以使用ntsysv关闭不需要开机启动的服务,当然也可以使用chkconfig工具来实现。
写一个shell脚本,用chkconfig工具把不常用的服务关闭。脚本需要写成交互式的,需要我们给它提供关闭的服务名字。
参考答案:
#!/bin/bash LANG=en c="1" while [ ! $c == "q" ] do echo -e "\033[35mPlease chose a service to close from this list: \033[0m" chkconfig --list |awk '/3:on/ {print $1}' read -p "Which service to close: " s chkconfig $s off service $s stop read -p "If you want's to quit this program, tab "q", or tab "Ctrl c": " c done
shell习题-统计并发量
需求背景:
需要统计网站的并发量,并绘图。
思路:
1 借助zabbix成图
2 通过统计访问日志每秒的日志条数来判定并发量
3 zabbix获取数据间隔30s
说明: 只需要写出shell脚本即可,不用关心zabbix配置。
参考答案:
假设日志路径 /data/logs/www.aaa.com_access.log 日志格式如下 112.107.15.12 - [07/Nov/2017: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)" #!/bin/bash log=/data/logs/www.aaa.com_access.log t=`date -d "-1 second" +%Y:%H:%M:%S` #可以大概分析一下每分钟日志的量级,比如说不超过3000 n=tail -3000 $log |grep -c "$t" echo $n
shell习题-批量同步代码
需求背景是:
一个业务,有3台服务器(A,B,C)做负载均衡,由于规模太小目前并未使用专业的自动化运维工具。有新的需求时,开发同事改完代码会把变更上传到其中一台服务器A上。但是其他2台服务器也需要做相同变更。
写一个shell脚本,把A服务器上的变更代码同步到B和C上。
其中,你需要考虑到不需要同步的目录(假如有tmp、upload、logs、caches)
参考答案:
#!/bin/bash echo "该脚本将会把A机器上的/data/wwwroot/www.aaa.com目录同步到B,C机器上"; read -p "是否要继续?(y|n) " rs() { rsync -azP \ --exclude logs \ --exclude upload \ --exclude caches \ --exclude tmp \ www.aaa.com/ $1:/data/wwwroot/www.aaa.com/ } if [ $REPLY == 'y' -o $REPLY == 'Y' ] then echo "即将同步……" sleep 2 cd /data/wwwroot/ rs B机器ip rs C机器ip echo "同步完成。" elif [ $REPLY == 'n' -o $REPLY == 'N' ] then exit 1 else echo "请输入字母y或者n" fi
shell习题-数组
写一个脚本让用户输入多个城市的名字(可以是中文),要求不少于5个,然后把这些城市存到一个数组里,最后用for循环把它们打印出来。
参考答案:
#!/bin/bash read -p "请输入至少5个城市的名字,用空格分隔:" city n=`echo $city|awk '{print NF}'` if [ $n -lt 5 ] then echo "输入的城市个数至少为5" exit fi name=($city) for i in ${name[@]} do echo $i done
shell习题-截取tomcat日志
写一个截取tomcat catalina.out日志的脚本
tomcat实例t1-t4
# tree -L 1 /opt/TOM/
/opt/TOM/
├── crontabs
├── t1
├── t2
├── t3
└── t4
5 directories, 0 files
# 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
要求:
1.这个脚本可以取tomcat实例t1-t4的日志
2.这个脚本可以自定义取日志的起始点 ,比如取今天早上10点之后到现在的数据
3.这个脚本可以自定义取日志的起始点和终点,比如取今天早上9点到晚上8点的数据
catalina.out 日志内容
Mar 29, 2016 1:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [“http-bio-8080”]
Mar 29, 2016 1:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [“ajp-bio-8009”]
Mar 29, 2016 1:52:24 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 2102 ms
参考答案:
#!/bin/bash ## #Author: 7期孙东 # export LANG=en_US.UTF-8 export PATH=$PATH IPADD=`/sbin/ifconfig | grep "inet addr" | head -1 | awk '{print $2}'| awk -F '.' '{print $NF}'` LOGFILE="/opt/TOM/$1/logs/catalina.out" YEAR=`date +%Y` DATE=`date +%m%d_%H%M` TOMCAT=$1 BEGIN_TIME=$YEAR$2 END_TIME=$YEAR$3 ##judge is a.m.or p.m. TIME_HOUR1=`echo ${BEGIN_TIME:9:2}` cut_log() { N_DATE1=`echo $1 | sed 's/_/ /g'` D_DATE1=`echo $2 | sed 's/_/ /g'` E_DATE1=`echo $3 | sed 's/_/ /g'` [ $4 ] && N_DATE2=`echo $4 | sed 's/_/ /g'` [ $5 ] && D_DATE2=`echo $5 | sed 's/_/ /g'` [ $6 ] && E_DATE2=`echo $6 | sed 's/_/ /g'` BEGIN=`grep -nE "${N_DATE1}|${D_DATE1}|${E_DATE1}" ${LOGFILE} | head -1 | cut -d : -f1` [ "$N_DATE2" ] && END=`grep -nE "${N_DATE2}|${D_DATE2}|${E_DATE2}" ${LOGFILE} | tail -1 | cut -d : -f1` [ ! -z "${TIME_HOUR1}" ] && if [ ${TIME_HOUR1} -gt 12 ] ; then BEGIN1=`grep -nE "${N_DATE1}|${D_DATE1}|${E_DATE1}" ${LOGFILE} |grep " PM " |grep "${E_DATE1}" | head -1 | cut -d : -f1` if [ ! -z "${BEGIN1}" ] ; then [ "${BEGIN1}" -gt "${BEGIN}" ] ; BEGIN=${BEGIN1} fi fi if [ "$BEGIN" ] && [ -z "$END" ] ; then if [ "$N_DATE2" ]; then echo "${END_TIME}时间点没有访问日志,请重新设置时间点." else sed -n "${BEGIN},[ DISCUZ_CODE_0 ]quot;p ${LOGFILE} > /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log fi elif [ "$END" ];then [ "$BEGIN" ] || BEGIN=1 sed -n "${BEGIN},${END}"p ${LOGFILE} > /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log else [ "$END_TIME" != "$YEAR" ] && echo "该时段 ${BEGIN_TIME}~${END_TIME} 没有日志." [ "$END_TIME" = "$YEAR" ] && echo "该时段 ${BEGIN_TIME}~now 没有日志." fi if [ -s /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log ]; then cd /home/gcweb && tar -zcf ${IPADD}_${TOMCAT}_${DATE}.tar.gz ${IPADD}_${TOMCAT}_${DATE}.log rm -f /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log sz /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.tar.gz echo "Success to get logs." rm -f /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.tar.gz fi } get_time() { case "$1" in 4) N_DATE=`date -d "$2" +"%Y-%m-%d" 2>/dev/null` D_DATE=`date -d "$2" +"%Y/%m/%d" 2>/dev/null` E_DATE=`date -d "$2" +"%h %e,_%Y" 2>/dev/null|sed 's/ /_/g'` echo $N_DATE $D_DATE $E_DATE ;; 7) TIME=`echo $2 | awk -F'_' '{print $1,$2}'` N_DATE=`date -d "$TIME" +"%Y-%m-%d_%H" 2>/dev/null` D_DATE=`date -d "$TIME" +"%Y/%m/%d_%H" 2>/dev/null` E_DATE=`date -d "$TIME" +"%h %e,_%Y %l" 2>/dev/null|sed 's/ /_/g'` echo "$N_DATE" "$D_DATE" "$E_DATE" ;; 9) TIME=`echo $2 | awk -F'_' '{print $1,$2}'` N_DATE=`date -d "$TIME" +"%Y-%m-%d_%H:%M" 2>/dev/null` D_DATE=`date -d "$TIME" +"%Y/%m/%d_%H:%M" 2>/dev/null` E_DATE=`date -d "$TIME" +"%h %e,_%Y %l:%M" 2>/dev/null|sed 's/ /_/g'` echo "$N_DATE" "$D_DATE" "$E_DATE" ;; *) echo 1 ;; esac } check_arguments () { if [ "$1" == 1 ] || [ -z "$1" ] ;then echo "你输入时间参数的格式无法识别, usage: 0108、0108_10、0108_1020" exit 3 fi } check_tomcat () { if [ ! -s "${LOGFILE}" ] ;then echo "tomcat_name: ${TOMCAT} is not exist" echo "you can choose:" /bin/ls /home/gcweb/usr/local/ fi if [ $1 -lt 2 ] || [ ! -s "${LOGFILE}" ];then echo "usage: $0 tomcat_name {begin_time|begin_time end_time}" exit 2 fi } case "$#" in 0) echo "usage: $0 tomcat_name {begin_time|begin_time end_time}" exit 1 ;; 1) check_tomcat $# ;; 2) check_tomcat $# len=`echo $2 | awk '{print length($0)}'` A_DATE=$(get_time $len $BEGIN_TIME) eval $( echo $A_DATE |awk '{print "N_DATE="$1,"D_DATE="$2,"E_DATE="$3}') check_arguments "${N_DATE}" cut_log "${N_DATE}" "${D_DATE}" "${E_DATE}" ;; 3) check_tomcat $# len1=`echo $2 | awk '{print length($0)}'` len2=`echo $3 | awk '{print length($0)}'` A_DATE=$(get_time ${len1} $BEGIN_TIME) eval $( echo $A_DATE |awk '{print "N_DATE1="$1,"D_DATE1="$2,"E_DATE1="$3}') check_arguments "${N_DATE1}" A_DATE=$(get_time ${len2} $END_TIME) eval $( echo $A_DATE |awk '{print "N_DATE="$1,"D_DATE="$2,"E_DATE="$3}') check_arguments "${N_DATE}" cut_log ${N_DATE1} ${D_DATE1} ${E_DATE1} "${N_DATE}" "${D_DATE}" "${E_DATE}" ;; *) echo "usage: $0 tomcat_name {begin_time|begin_time end_time};你使用的参数太多哦." ;; esac
shell习题-监控磁盘io
阿里云的机器,今天收到客服来的电话,说服务器的磁盘io很重。于是登录到服务器查看,并没有发现问题,所以怀疑是间歇性地。
正要考虑写个脚本的时候,幸运的抓到了一个线索,造成磁盘io很高的幕后黑手是mysql。此时去show processlist,但未发现队列。原来只是一瞬间。
只好继续来写脚本,思路是,每5s检测一次磁盘io,当发现问题去查询mysql的processlist。
帮助:你可以用iostat -x 1 5 来判定磁盘的io,主要看%util
参考答案:
#!/bin/bash while : do n=`iostat -x 1 5 |tail -n3|head -n1 |awk '{print $NF}'|cut -d. -f1` if [ $n -gt 70 ] then echo "`date` util% is $n%" >>/tmp/mysql_processlist.log mysql -uroot -pxxxxxx -e "show full processlist" >> /tmp/mysql_processlist.log fi sleep 5 done
shell习题-自动增加公钥
2017年11月20日
shell习题
No Comments
aming
写一个shell脚本,当我们执行时,提示要输入对方的ip和root密码,然后可以自动把本机的公钥增加到对方机器上,从而实现密钥认证。
参考答案: