@老男孩Shell企业面试题
shell
2016年9月7日
本文来自于老男孩教育,未经本人同意,禁止转载!否则追究法律责任。
原文:http://oldboy.blog.51cto.com/2561410/1632876
企业面试题1:
(生产实战案例):监控
MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员。提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟:
阶段1:开发一个守护进程脚本每30秒实现检测一次。
阶段2:如果同步出现如下错误号(1158
,1159
,1008
,1007
,1062
),则跳过错误
。
阶段3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)
[root@oldboy~]# mysql -uroot -p'oldboy' -S /data/3307/mysql.sock -e "show slavestatus\G;" *************************** 1. row *************************** Slave_IO_State:Waiting for master to send event Master_Host:10.0.0.179 #当前的mysql master服务器主机 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File:mysql-bin.000013 Read_Master_Log_Pos: 502547 Relay_Log_File:relay-bin.000013 Relay_Log_Pos:251 Relay_Master_Log_File:mysql-bin.000013 Slave_IO_Running:Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: mysql Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 502547 Relay_Log_Space:502986 Until_Condition:None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 #和主库比同步延迟的秒数,这个参数很重要 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error:
本脚本由李佳豪同学分享
[root@db02 tmp]# cat MySQL主从监控.sh #!/bin/bash Mysql="mysql -uroot -poldboy123 -S /data/3307/mysql.sock" L_aaa(){ Status=`$Mysql -e "show slave status\G" | grep -E "_Running: Yes|Seconds_Behind_Master: [0-2]" | wc -l` Code=`$Mysql -e "show slave status\G" | awk '/Last_SQL_Errno:/{print $2}'` } L_Status(){ [ $Status -ne 3 ] && { return 1 } || { return 0 } } S_Code=( 1158 1159 1008 1007 1062 ) L_Skip(){ [ $Code -eq 0 ] && return 0 for i in ${S_Code[*]} do [ $Code -eq $i ] && { $Mysql -e "stop slave;set global sql_slave_skip_counter = 1;start slave;" && \ return 0 } done return 1 } main(){ while true do L_aaa L_Skip Error1=$? L_Status Error2=$? [ $Error1 -eq 1 -o $Error2 -eq 1 ] && echo "Error" done } main
企业面试题2:
使用for
循环在/oldboy
目录下通过随机小写10
个字母加固定字符串oldboy批量创建10
个html文件,名称例如为:
[root@oldboy oldboy]# sh /server/scripts/oldboy.sh [root@oldboy oldboy]# ls coaolvajcq_oldboy.html qnvuxvicni_oldboy.html vioesjmcbu_oldboy.html gmkhrancxh_oldboy.html tmdjormaxr_oldboy.html wzewnojiwe_oldboy.html jdxexendbe_oldboy.html ugaywanjlm_oldboy.html xzzruhdzda_oldboy.html qcawgsrtkp_oldboy.html vfrphtqjpc_oldboy.html
脚本如下:
[root@db02 ~]# sh html.sh [root@db02 ~]# ls /oldboy/ aebccciiaj_oldboy.html fffabecgbc_oldboy.html afffebcchb_oldboy.html ffghcffegb_oldboy.html dbccddabbj_oldboy.html hffbhfgdff_oldboy.html ehbdaedach_oldboy.html jadafhbaaf_oldboy.html fbaacihehi_oldboy.html jgfebjbebd_oldboy.html [root@db02 ~]# cat html.sh #!/bin/bash . /etc/init.d/functions [ -d /oldboy ]|| mkdir -p /oldboy cd /oldboy for i in `seq 10` do touch `echo $RANDOM|md5sum|cut -c 1-10|tr "[0-9]" "[a-z]"`_oldboy.html done
企业面试题3:
请用至少两种
方法实现!
将以上文件名中的oldboy全部改成oldgirl(用for
循环实现),并且html改成大写。
第一种方法:
[root@db02 ~]# sh html1.sh [root@db02 ~]# ll /oldboy/ total 0 -rw-r--r-- 1 root root 0 Jul 20 20:45 aebccciiaj_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 afffebcchb_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 dbccddabbj_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 ehbdaedach_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 fbaacihehi_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 fffabecgbc_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 ffghcffegb_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 hffbhfgdff_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 jadafhbaaf_oldboy.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 jgfebjbebd_oldboy.HTML [root@db02 ~]# cat html1.sh #!/bin/bash cd /oldboy for i in `cd /oldboy` do rename "oldboy" "oldgirl" *.html|rename "html" "HTML" *.html done
第二种方法:
[root@db02 ~]# sh html2.sh [root@db02 ~]# ll /oldboy/ total 0 -rw-r--r-- 1 root root 0 Jul 20 20:45 aebccciiaj_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 afffebcchb_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 dbccddabbj_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 ehbdaedach_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 fbaacihehi_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 fffabecgbc_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 ffghcffegb_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 hffbhfgdff_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 jadafhbaaf_oldgirl.HTML -rw-r--r-- 1 root root 0 Jul 20 20:45 jgfebjbebd_oldgirl.HTML [root@db02 ~]# cat html2.sh #!/bin/bash cd /oldboy for i in `ls *.HTML` do mv $i `echo $i|sed -e 's#oldboy#oldgirl#g;s#html#HTML#g'` done
补充:QQ 1163718639
[root@db01 shell30]# cat 3.sh #!/bin/bash for i in /oldboy/* do rename oldboy. oldgir. $i|echo oldgirlok done for x in /oldboy/* do rename html HTML $x|echo htmlok done [root@db01 shell30]#
企业面试题4:
批量创建10
个系统帐号oldboy01-oldboy10
并设置密码(密码为随机
8位字符串)。
[root@db02 tmp]# cat useradd.sh #!/bin/bash [ $UID -ne 0 ]&& echo "only root run"&&exit 1 [ -f /etc/init.d/functions ]&& . /etc/init.d/functions isexist() { result=$(grep -w "^$1" /etc/passwd|wc -l) if [ $result -ne 0 ];then echo "user $1 is exist!!" ret 1 "create user is " continue fi } ret() { if [ $1 -eq 0 ];then action "$2" /bin/true else action "$2" /bin/false fi } create() { for i in $(seq -w 10) do user="oldboy$i" isexist $user pass=$(cat /proc/sys/kernel/random/uuid|md5sum|cut -c 1-10) useradd $user&&echo $pass|passwd --stdin $user &>/dev/null ret $? "crate user $user" echo "$user $pass" >> /tmp/user.list done } main() { create } main
企业面试题5:
写一个脚本,实现判断10.0.0.0/24
网络里,当前在线用户的IP有哪些(方法有很多)
本脚本由刘沈晨分享
注意:此脚本使用nmap
,如果没有需要使用yum -y install nmap
[root@db02 scripts]# cat test_5.sh #!/bin/sh # [ -f /etc/init.d/functions ] && . /etc/init.d/functions function IP_count(){ for n in 10.0.0.{0..255} do IP_check=`nmap -sP $n|grep "Host is up"|wc -l` if [ ${IP_check} -eq 1 ];then action "$n" /bin/true let i+=1 fi done } function main(){ IP_count echo "The total number of online IP Addresses is " $i } main
企业实战题6:
写一个脚本解决DOS
攻击生产案例
提示:根据web
日志或者或者网络
连接数,监控当某个IP并发连接数或者短时内PV达到100
,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟。防火墙命令为:iptables -I INPUT -s 10.0.1.10 -j DROP。
本脚本使用测试文件进行编写:模拟文件下载 链接:http://pan.baidu.com/s/1gfqeHaz 密码:3usn
[root@db02 scripts]# cat test_6.sh #!/bin/sh # [ -f /etc/init.d/functions ] && . /etc/init.d/functions IP_file="/server/scripts/ddos.txt" IP_filter_command="iptables -I INPUT -j DROP -s" IP_recover_command="iptables -D INPUT -j DROP -s" function IP_check(){ grep "EST" ${IP_file}|awk -F "[ |:]+" '{print $6}'|sort |uniq -c|sort -rn -k1 > /server/scripts/ip.txt } function IP_filter(){ exec < /server/scripts/ip.txt while read line do IP_count=`echo $line|awk '{print $1}'` IP=`echo $line|awk '{print $2}'` IP_fil=`iptables -L -n|grep "\b${IP}\b"|wc -l` if [ ${IP_count} -gt 25 -a ${IP_fil} -eq 0 ];then ${IP_filter_command} ${IP} echo "${IP}" >> /server/scripts/ip_filtered.txt action "Filter ${IP}" /bin/true fi done } function IP_recover(){ exec < /server/scripts/ip.txt while read line do IP_count=`echo $line|awk '{print $1}'` IP=`echo $line|awk '{print $2}'` IP_fil=`iptables -L -n|grep "\b${IP}\b"|wc -l` if [ ${IP_count} -le 25 -a ${IP_fil} -eq 1 ];then ${IP_recover_command} ${IP} echo "${IP}" >> /server/scripts/ip_filtered.txt action "Recover ${IP}" /bin/true fi done } function main(){ case "$1" in filter) IP_check echo "$(date +%F-%H:%M:%S) filtered by $(whoami)" >> /server/scripts/ip_filtered.txt IP_filter ;; recover) IP_check echo "$(date +%F-%H:%M:%S) recovered by $(whoami)" >> /server/scripts/ip_filtered.txt IP_recover ;; *) echo "USAGE:$0 {filter|recover}" exit 1 esac } main $*
企业实战题7:
开发mysql多实例启动脚本:
已知mysql多实例启动命令为:mysqld_safe--defaults-file=/data/3306/my.cnf &
停止命令为:mysqladmin -u root -poldboy123 -S /data/3306/mysql.sockshutdown
请完成mysql
多实例启动启动脚本的编写
要求:用函数,case语句、if语句等实现
1.第一种方法:比较简单,适用于一台MySQL服务器上 [root@db02 mysql]# cat mysql.sh #!/bin/bash ########################### #I am YuhongCong #qq:604419314 ########################## [ -f /etc/init.d/functions ]&& . /etc/init.d/functions #config prot=3306 mysql_user=root mysql_paswd=123456 Path=/data/3306/ mysql_start(){ if [ -f ${Path}mysqld.pid ];then echo "MySQL is running" exit 1 else mysqld_safe --defaults-file=${Path}my.cnf &>/dev/null & if [ $? -eq 0 ];then action "MySQL is starting" /bin/true else action "MySQL no start" /bin/false fi fi } mysql_stop(){ if [ ! -f ${Path}mysqld.pid ];then echo "Mysql not running" else mysqladmin -u ${mysql_user} -p${mysql_paswd} -S ${Path}mysql.sock shutdown if [ $? -eq 0 ];then action "mysql is stop" /bin/true else action "mysql no stop" /bin/false fi fi } case "$1" in start) mysql_start ;; stop) mysql_stop ;; restart) mysql_stop sleep 3 mysql_start ;; *) echo "Please input {start|stop|restart}" ;; esac
第二种方法:应强哥及李啸宇、大欣等要求进行改版。
适用于管理多实例启动的脚本
[root@db02 tmp]# cat mysqlgood.sh #!/bin/bash ################## #I am yuhongcong #qq:604419314 ################# [ -f /etc/init.d/functions ]&& . /etc/init.d/functions prot=3306 mysql_user=root mysql_paswd=123456 Path=/data/3306/ ############################################# cat </dev/null & if [ $? -eq 0 ];then action "mysql 3306 is starting" /bin/true else action "mysql 3306 not start" /bin/false fi fi } mysql1_stop(){ if [ ! -f ${Path}mysqld.pid ];then echo "mysql 3306 not running" else mysqladmin -u ${mysql_user} -p${mysql_paswd} -S /data/3306/mysql.sock shutdown if [ $? -eq 0 ];then action "mysql 3306 is stopping" /bin/true else action "mysql 3306 no stop" /bin/false fi fi } mysql2_start(){ if [ -f /data/3307/mysqld.pid ];then echo "MySQL 3307 is runningx" else mysqld_safe --defaults-file=/data/3307/my.cnf &>/dev/null & if [ $? -eq 0 ];then action "mysql 3307 is starting" /bin/true else action "mysql 3307 not start" /bin/false fi fi } mysql2_stop(){ if [ ! -f /data/3307/mysqld.pid ];then echo "mysql 3307 not running" else mysqladmin -u ${mysql_user} -p${mysql_paswd} -S /data/3307/mysql.sock shutdown if [ $? -eq 0 ];then action "mysql 3307 is stopping" /bin/true else action "mysql 3307 no stop" /bin/false fi fi } aaa(){ cat < 企业实战题8: 如何实现对MySQL数据库进行分库备份,请用脚本实现 本文由刘康同学提供 [root@db02 tmp]# cat MoreDatabasesBak.sh #!/bin/bash . /etc/init.d/functions PORT='3306' BAKUPDIR='/server/backup' MYSQLUSER='root' MYSQLPASS='oldboy' SOCK="/data/${PORT}/mysql.sock" CMDDIR="/application/mysql/bin" MYSQL="${CMDDIR}/mysql -u${MYSQLUSER} -p${MYSQLPASS} -S${SOCK}" DBNAME=`${MYSQL} -e "show databases;"|sed 1d|egrep -v "_schema|mysql"` AYYAYDB=($DBNAME) MYSQLDUMP="${CMDDIR}/mysqldump -u${MYSQLUSER} -p${MYSQLPASS} -S${SOCK}" function BAKDB(){ for((n=0;n<${#AYYAYDB[*]};n++)) do ${MYSQLDUMP} --events -B ${AYYAYDB[$n]} |gzip >${BAKUPDIR}/${AYYAYDB[$n]}_$(date +%T-%F)_bak.sql.gz RETVAL=$? if [ $RETVAL -eq 0 ] then echo "${AYYAYDB[$n]} bak successfull `date +%F-%T` " >>/tmp/DBbakstatus.log else echo "${AYYAYDB[$n]} bak fail `date +%F-%T` " >>/tmp/DBbakstatus.log fi done mail -s "DB STATUS" www.abcdocker.com@qq.com < /tmp/DBbakstatus.log return } function DBstatus(){ [ -d ${BAKUPDIR} ] || mkdir ${BAKUPDIR} -p ${MYSQL} -e "show full processlist;" &> /dev/null RETVAL=$? if [ $RETVAL -eq 0 ] then >/tmp/DBbakstatus.log BAKDB else echo "DB BAD!!! `date +%F-%T`" | mail -s "DB BAD!!!" www.abcdocker.com@qq.com exit fi } DBstatus 企业实战题9: 如何实现对MySQL数据库进行分库加分表备份,请用脚本实现 本脚本还是由刘康同学提供 [root@db02 tmp]# cat MoreTablesBak.sh #!/bin/bash . /etc/init.d/functions PORT='3306' BAKUPDIR='/server/backup' MYSQLUSER='root' MYSQLPASS='oldboy' SOCK="/data/${PORT}/mysql.sock" CMDDIR="/application/mysql/bin" MYSQL="${CMDDIR}/mysql -u${MYSQLUSER} -p${MYSQLPASS} -S${SOCK}" DBNAME=`${MYSQL} -e "show databases;"|sed 1d|egrep -v "_schema|mysql"` AYYAYDB=($DBNAME) MYSQLDUMP="${CMDDIR}/mysqldump -u${MYSQLUSER} -p${MYSQLPASS} -S${SOCK}" function BAKDB(){ DBNAME=`${MYSQL} -e "show databases;"|sed 1d|egrep -v "_schema|mysql"` AYYAYDB=($DBNAME) for((n=0;n<${#AYYAYDB[*]};n++)) do TABLE_BAK_DIR="${BAKUPDIR}/${AYYAYDB[$n]}" TABLENAME=`${MYSQL} -e "show tables from ${AYYAYDB[$n]};"|sed 1d` ARRAYTABLE=(${TABLENAME}) for((i=0;i<${#ARRAYTABLE[*]};i++)) do [ -d ${TABLE_BAK_DIR} ] || mkdir ${TABLE_BAK_DIR} -p ${MYSQLDUMP} ${AYYAYDB[$n]} ${ARRAYTABLE[$i]} |gzip >${TABLE_BAK_DIR}/${ARRAYTABLE[$i]}_$(date +%T-%F)_bak.sql.gz RETVAL=$? if [ $RETVAL -eq 0 ] then echo "${AYYAYDB[$n]}_${ARRAYTABLE[$i]} bak successfull `date +%F-%T` " >>/tmp/DB_table_bakstatus.log else echo "${AYYAYDB[$n]}_${ARRAYTABLE[$i]} bak fail `date +%F-%T` " >>/tmp/DB_table_bakstatus.log fi done done mail -s "DB STATUS" www.abcdocker.com@qq.com < /tmp/DB_table_bakstatus.log return } function DBstatus(){ [ -d ${BAKUPDIR} ] || mkdir ${BAKUPDIR} -p ${MYSQL} -e "show full processlist;" &> /dev/null RETVAL=$? if [ $RETVAL -eq 0 ] then >/tmp/DB_table_bakstatus.log BAKDB else echo "DB BAD!!! `date +%F-%T`" | mail -s "DB BAD!!!" www.abcdocker.com@qq.com exit fi } DBstatus 企业面试题10: 请用至少两种方法实现! bash for循环打印下面这句话中字母数不大于6的单词(昆仑万维面试题)。 I am oldboy teacher welcome to oldboy training class. 没讲数组之前自己做的: [root@web02 ~]# cat /server/scripts/28/bash.sh #!/bin/bash for n in `echo I am oldboy teacher welcome to oldboy training class.` do AAA=$( echo $n|wc -c) if [ $AAA -gt 7 ];then continue; fi echo $n done 第一种方法:不使用数组 [root@db02 scripts]# cat 3.sh #!/bin/bash for i in I am oldboy teacher welcome to oldboy training class. do if [ "${#i}" -le 6 ] then echo $i fi done 第二种方法:使用数组 [root@db02 scripts]# cat 3.sh #!/bin/bash array=(I am oldboy teacher welcome to oldboy training class.) for ((i=0;i<${#array[@]};i++)) do if [ "`echo ${array[i]}|wc -L`" -le 6 ] then echo ${array[i]} fi done 第三种方法:命令拼接 echo "I am oldboy teacher welcome to oldboy training class." | awk '{for(i=1;i<=NF;i++){a=length($i);if(a <= 6){print $i}}}' 企业面试题11: 开发shell脚本分别实现以脚本传参以及read读入的方式比较2个整数大小。以屏幕输出的方式提醒用户比较结果。注意:一共是开发2个脚本。当用脚本传参以及read读入的方式需要对变量是否为数字、并且传参个数做判断。 [root@db01 scripts]# cat read.sh #!/bin/sh #no.1 read -p "Pls input two num:" a b [ -z "$a" -o -z "$b" ]&&{ echo "must be two num." exit 1 } #no.2 expr $a + 1 &>/dev/null [ $? -ne 0 ]&&{ echo "First arg must be int." exit 2 } expr $b + 1 &>/dev/null [ $? -ne 0 ]&&{ echo "Second arg must be int." exit 3 } #no.3 [ $a -gt $b ]&&{ echo "$a > $b" exit 0 } [ $a -eq $b ]&&{ echo "$a = $b" exit 0 } [ $a -lt $b ]&&{ echo "$a < $b" exit 0 } 企业面试题12: 打印选择菜单,一键安装Web服务: [root@oldboyscripts]# sh menu.sh 1.[install lamp] 2.[install lnmp] 3.[exit] pls input the num you want: 要求: 1、当用户输入1时,输出“startinstalling lamp.”然后执行/server/scripts/lamp.sh,脚本内容输出"lampis installed"后退出脚本; 2、当用户输入2时,输出“startinstalling lnmp.”然后执行/server/scripts/lnmp.sh输出"lnmpis installed"后退出脚本; 3、当输入3时,退出当前菜单及脚本; 4、当输入任何其它字符,给出提示“Input error”后退出脚本。 5、要对执行的脚本进行相关条件判断,例如:脚本是否存在,是否可执行等。 由10组黑哥提供(吴依) 黑哥博客:www.dockerwy.com #!/bin/bash cat < 企业面试题13: 1、监控web服务是否正常,不低于3种监控策略。 2、监控db服务是否正常,不低于3种监控策略。 要求间隔1分钟,持续监控。 思路 1、监控的三种方式 通过进程名监控 ps -ef|grep name 通过端口监控 netstat -lntup|grep port/lsof -i:80 通过链接信息上的进程名 netstat -lntup|grep port 2、等待一分钟 3、后台执行 nohup #!/bin/bash [ -f /etc/init.d/functions ] && . /etc/init.d/functions check_httpd(){ count=`ps -ef|grep nginx|grep -v grep|wc -l` if [ "$count" -ne 0 ] then action "nginx is ok" /bin/true else action "nginx is dead" /bin/false fi } check_httpd_port(){ count=`netstat -lntup|grep 8080|wc -l` if [ "$count" -ne 0 ] then action "nginx is ok" /bin/true else action "nginx is dead" /bin/false fi } 企业面试题14: 监控memcache服务是否正常,模拟用户(web客户端)检测。 使用nc命令加上set/get来模拟检测,以及监控响应时间及命中率。 感谢乔飞翔同学的分享 [root@db02 scripts]# cat mem.sh #!/bin/bash ######################## #date:2016-07-17 # #author:fxqiao # #QQ:827724746 # #E-mail:qfx1995@163.com# ######################## #echo -ne "\033[0;33m" echo -ne "\E[1;32m" cat<_/___.' >' "". | | : '- \'.;'\ _ /';.'/ - ' : | | \ \ '_. \_ __\ /__ _/ .-' / / ====='-.____'.___ \_____/___.-'____.-'===== '=---=' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 佛祖保佑 iii 服务正常 EOT echo -ne "\E[0m" [ -f /etc/init.d/functions ] && . /etc/init.d/functions ###variables RETVAL=0 ###color RED_COLOR='\E[1;31m' GREEN_COLOR='\E[1;32m' YELLOW_COLOR='\E[1;33m' BLUE_COLOR='\E[1;34m' RES='\E[0m' ####menu list menu() { cat < ############################ 1 memcached status 2 memcached stop 3 memcached get_hits 4 quit EOF } status() { Set=$(printf "set key1 0 0 6\r\noldboy\r\n"|nc 127.0.0.1 11211|grep STORED|wc -l) Get=$(printf "get key1\r\n"|nc 127.0.0.1 11211|grep oldboy|wc -l) Port=$(netstat -lntup|grep memcached|wc -l) if [ $Port -ge 4 ];then Num=$(expr $Set + $Get) if [ $Num -eq 2 ];then action "Memcached server is running" /bin/true else action "Memcached server is not normal" /bin/false fi else action "Memcached server is not running" /bin/false read -t 10 -p "Memcached server whether open:[y/n]:" b if [ "$b" == "y" -o "$b" == "Y" ];then /usr/bin/memcached -m 16m -p 11211 -d -u root -c 8192 action "Memcached server is starting" /bin/true elif [ "$b" == "n" -o "$b" == "N" ];then echo -e "$YELLOW_COLOR Goodbye.............$RES" fi fi return $RETVAL } stop() { Port=$(netstat -lntup|grep memcached|wc -l) if [ $Port -ge 4 ];then pkill memcached &>/dev/null RETVAL=$? if [ $RETVAL -eq 0 ];then action "Memcached server is stopping" /bin/true else action "Memcached server is stopping" /bin/false fi else action "Memcached server not running" /bin/false fi } get_hits() { Cmd_get=$(printf "stats\r\n"|nc 127.0.0.1 11211|grep "cmd_get"|awk '{print $3}') Get_hits=$(printf "stats\r\n"|nc 127.0.0.1 11211|grep "get_hits"|awk '{print $3}') Get_misses=$(printf "stats\r\n"|nc 127.0.0.1 11211|grep "get_misses"|awk '{print $3}') Port=$(netstat -lntup|grep memcached|wc -l) if [ $Port -ge 4 ];then echo "A total of cmd_get is $Cmd_get" sleep 1 echo "A total of get_hits is $Get_hits" sleep 1 echo "A total of get_misses is $Get_misses" else action "Memcached is not running" /bin/false fi return $RETVAL } main() { while true do menu read -t 10 -p "Please input number:" a expr $a + 1 &>/dev/null if [ $? -ne 0 ];then echo -e "$BLUE_COLOR Please input error,not int $RES" exit 1 fi case "$a" in 1) status RETVAL=$? ;; 2) stop RETVAL=$? ;; 3) get_hits RETVAL=$? ;; 4) clear echo "##############################################" echo -e "$GREEN_COLOR `figlet GoodBye` $RES" echo "##############################################" exit 0 ;; *) echo -e "$RED_COLOR input error $RES" esac done } main exit $RETVAL 企业面试题15: 面试及实战考试题:监控web站点目录(/var/html/www)下所有文件是否被恶意篡改(文件内容被改了),如果有就打印改动的文件名(发邮件),定时任务每3分钟执行一次(10分钟时间完成)。 [root@db02 tmp]# cat html.sh #!/bin/sh html_dir=/var/html/www html_file=`find /var/html/www -type f` check_dir=/tmp/checkdir [ ! -d $check_dir ] && mkdir $check_dir for n in $html_file do md5sum $n >>$check_dir/1.txt done while true do md5sum -c $check_dir/1.txt|grep FAILED >>$check_dir/2.txt [ -s $check_dir/2.txt ] && \ echo "`cat $check_dir/2.txt`"|mail -s "date:`date +%F-%H:%M:%S` Web is dangerous" 18576749166@163.com >$check_dir/2.txt sleep 3 done 企业面试题16: 企业案例:写网络服务独立进程模式下rsync的系统启动脚本 例如:/etc/init.d/rsyncd{start|stop|restart}。 要求: 1.要使用系统函数库技巧。 2.要用函数,不能一坨SHI的方式。 3.可被chkconfig管理。 [root@www tmp]# cat 123.sh #!/bin/bash ################## #I am yuhongcong #qq:604419314 ################# # Comments to support chkconfig on RedHat Linux # chkconfig: 2345 64 36 status1=$(ps -ef | egrep "rsync --daemon.*rsyncd.conf" | grep -v 'grep') pidfile="/etc/rsync/rsyncd.pid" start_rsync="rsync --daemon --config=/etc/rsync/rsyncd.conf" function rsyncstart() { if [ "${status1}X" == "X" ];then rm -f $pidfile ${start_rsync} status2=$(ps -ef | egrep "rsync --daemon.*rsyncd.conf" | grep -v 'grep') if [ "${status2}X" != "X" ];then echo "rsync service start.......OK" fi else echo "rsync service is running !" fi } function rsyncstop() { if [ "${status1}X" != "X" ];then kill -9 $(cat $pidfile) status2=$(ps -ef | egrep "rsync --daemon.*rsyncd.conf" | grep -v 'grep') if [ "${statusw2}X" == "X" ];then echo "rsync service stop.......OK" fi else echo "rsync service is not running !" fi } function rsyncstatus() { if [ "${status1}X" != "X" ];then echo "rsync service is running !" else echo "rsync service is not running !" fi } function rsyncrestart() { if [ "${status1}X" == "X" ];then echo "rsync service is not running..." rsyncstart else rsyncstop rsyncstart fi } case $1 in "start") rsyncstart ;; "stop") rsyncstop ;; "status") rsyncstatus ;; "restart") rsyncrestart ;; *) echo echo "Usage: $0 start|stop|restart|status" echo esac 企业面试题17: 老男孩教育天津项目学生实践抓阄题目: 好消息,老男孩培训学生外出企业项目实践机会(第6次)来了(本月中旬),但是,名额有限,队员限3人(班长带队)。 因此需要挑选学生,因此需要一个抓阄的程序: 要求: 1、执行脚本后,想去的同学输入英文名字全拼,产生随机数01-99之间的数字,数字越大就去参加项目实践,前面已经抓到的数字,下次不能在出现相同数字。 2、第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入。 [root@db02 tmp]# cat select17.sh #!/bin/sh > /tmp/temp.txt input(){ while true do read -p "pls input your name:" name if [ -z $name ] then continue elif [ $name == "0" ] then break fi rand=$((RANDOM%100)) echo -e $rand"\t"$name >>/tmp/temp.txt done } output(){ cat /tmp/temp.txt |sort -n -k1 -r|sed '3a#################' } main(){ input output } main 企业面试题18: 已知下面的字符串是通过RANDOM随机数变量md5sum|cut-c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字? 21029299 00205d1c a3da1677 1f6d12dd 890684b 方法一: #!/bin/bash . /etc/init.d/functions MD5PASS=( 21029299 00205d1c a3da1677 1f6d12dd 890684b ) for ((n=0;n<=32767;n++)) do for((i=0;i<${#MD5PASS[*]};i++)) do md5=`echo $n | md5sum|cut -c 1-8` if [ "$md5" == ${MD5PASS[$i]} ] then echo "$n" "${MD5PASS[$i]} " fi done done 方法二: [root@openvpn-server ~]# cat md5sum.sh #!/bin/sh a=( 21029299 00205d1c a3da1677 1f6d12dd 890684b ) for i in `seq 32767` do source=`echo $i|md5sum|cut -c 1-8` for j in ${a[@]} do if [ $source == $j ];then echo $source "-->" $i fi done done 方法三: [root@m01 ~]# cat mianshiti6.sh #!/bin/bash mima=( 21029299 00205d1c a3da1677 1f6d12dd 890684b ) for i in {1..32767} do num=`echo $i | md5sum | cut -c -8` for n in ${mima[*]} do if [ "$num" == "$n" ] then echo "$i match $n" continue fi done done 企业面试题19: 批量检查多个网站地址是否正常 要求: shell数组方法实现,检测策略尽量模拟用户访问思路 http://www.etiantian.org http://www.taobao.com http://oldboy.blog.51cto.com http://10.0.0.7 [root@db02 scripts]# cat aaa.sh #!/bin/sh ################ #Author:YuHongCong #604419314@qq.com ################ [ -f /etc/init.d/functions ] && . /etc/init.d/functions URLS=( http://www.etiantian.org http://www.taobao.com http://oldboy.blog.51cto.com http://10.0.0.70 ) CHECK_URL(){ wget -T 3 --spider --tries=2 $1 &>/dev/null if [ $? -eq 0 ] then return 0 else return 1 fi } MON_URL(){ for url in ${URLS[*]} do CHECK_URL $url if [ $? -eq 0 ] then action "$url" /bin/true else action "$url" /bin/false fi done } main(){ while true do MON_URL sleep 10 done } main 老男孩推荐:(包含倒计时的方法) [root@db01 shizhan]# cat oldboy01.sh #!/bin/sh ################ #Author:oldboy #31333741@qq.com ################ [ -f /etc/init.d/functions ] && . /etc/init.d/functions URLS=( http://www.etiantian.org http://www.taobao.com http://oldboy.blog.51cto.com http://10.0.0.70 ) LTIME(){ echo -n "time;" for n in {1..10} do if [ $n -eq 10 ] then echo "start" else echo -n . fi sleep 1 done } CHECK_URL(){ wget -T 3 --spider --tries=2 $1 &>/dev/null if [ $? -eq 0 ] then return 0 else return 1 fi } MON_URL(){ for url in ${URLS[*]} do CHECK_URL $url if [ $? -eq 0 ] then action "$url" /bin/true else action "$url" /bin/false fi done } main(){ while true do LTIME MON_URL sleep 10 done } main
企业面试题20(中企动力): 用shell处理以下内容 1、按单词出现频率降序排序! 2、按字母出现频率降序排序! the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support sections for more infomation #!/bin/sh str="the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support sections for more infomation" words(){ echo $str|sed 's#[^a-zA-Z]# #g'|tr " " "\n"|grep -v "^$"|sort|uniq -c|sort -r -n } letters(){ echo $str|grep -o "."|sort|egrep -v " |^$|[^a-zA-Z]"|uniq -c|sort -n -r } case $1 in words) words ;; letters) letters ;; *) echo "usage:$0 {words|letters}" esac 企业面试题22: 开发通过web界面展示监控Nginx代理节点状态,效果图如下。
文件打包 密码:xso0 脚本及内容请下载
lvs+keepalived集群部分Shell企业案例: 企业面试题23、 【LVS主节点】手工开发ipvsadm管理lvs的脚本ip_vs 实现:/etc/init.d/lvs {start|stop|restart} [root@www tmp]# cat lvs.sh #!/bin/bash if [ $UID -ne 0 ];then echo "Permission denied (you must be root)" exit 1 fi [ -f /etc/init.d/functions ] && . /etc/init.d/functions vip_netmask=10.0.0.3/24 vip=10.0.0.3 service_addr=10.0.0.3:80 rs=( 10.0.0.7:80 10.0.0.8:80 ) start() { #add vip ifconfig|grep $vip &>/dev/null if [ $? -ne 0 ];then ip addr add $vip_netmask dev eth0 label eth0:0 && \ action "add vip $vip_netmask" /bin/true else echo "vip $vip_netmask already exists." fi lvs_table=$(ipvsadm -ln|grep "$vip"|wc -l) if [ $lvs_table -eq 1 ];then echo "virtual server already exists." else #add virtual server ipvsadm -A -t $service_addr -s wrr && \ action "add virtual server $service_addr" /bin/true fi for ip in ${rs[@]};do rs_num=$(ipvsadm -ln|grep "$ip"|wc -l) if [ $rs_num -eq 1 ];then echo "real server $ip already exists." else #add real server ipvsadm -a -t $service_addr -r $ip -g -w 1 && \ action "add real server $ip" /bin/true fi done #set tcp tcpfin udp connection timeout ipvsadm --set 30 5 60 && \ action "set tcp tcpfin udp connection timeout values." /bin/true } stop() { ifconfig|grep $vip &>/dev/null if [ $? -ne 0 ];then echo "without vip $vip" else #delete vip ip addr del $vip_netmask dev eth0 label eth0:0 && \ action "delete vip $vip_netmask." /bin/true fi lvs_table=$(ipvsadm -ln|grep "$vip"|wc -l) for ip in ${rs[@]};do rs_num=$(ipvsadm -ln|grep "$ip"|wc -l) let lvs_table+=rs_num done if [ $lvs_table -ge 1 ];then #clear all table ipvsadm -C && \ action "clear all lvs table." /bin/true else echo "lvs table is empty." fi } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 2 start ;; *) echo "USAGE: $0 {start|stop|restart}" esac 企业面试题24 【LVS主节点】模拟keepalived健康检查功能管理LVS节点, 当节点挂掉(检测2次,间隔2秒)从服务器池中剔除,好了(检测2次,间隔2秒)加进来 提示:利用ipvsadm命令实现添加和减少LVS节点。 [root@www tmp]# cat lvs_check_rs.sh #!/bin/bash vip=10.0.0.3 rs_ip=( 10.0.0.8 10.0.0.7 ) remove_check() { for rs in ${rs_ip[@]};do ipvsadm -ln|grep $rs &>/dev/null if [ $? -eq 0 ];then rs_donw=0 a_group_down=0 for i in 1 2;do rs_down=$(nmap -p 80 $rs|grep open|wc -l) let a_group_down+=rs_down sleep 2 done if [ $a_group_down -eq 0 ];then ipvsadm -d -t ${vip}:80 -r ${rs}:80 fi fi done } join_check() { for rs in ${rs_ip[@]};do ipvsadm -ln|grep $rs &>/dev/null if [ $? -ne 0 ];then a_group_up=0 rs_up=0 for j in 1 2;do rs_up=$(nmap -p 80 $rs|grep open|wc -l) let a_group_up+=rs_up sleep 2 done if [ $a_group_up -eq 2 ];then ipvsadm -a -t ${vip}:80 -r ${rs}:80 -g -w 1 fi fi done } check_rs() { while true;do remove_check sleep 1 join_check sleep 1 done } check_rs 企业面试题25 【LVS客户端节点】开发LVS客户端设置VIP以及抑制ARP的管理脚本 实现:/etc/init.d/lvsclient {start|stop|restart} [root@web01-lnmp-09 scripts]# cat /etc/init.d/lvsclient #!/bin/bash #chkconfig: 2345 37 57 #Write by Bevin 2016 #LVS_Nginx export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [ -f /etc/init.d/functions ] && source /etc/init.d/functions #Step 1 function L_ipadd() { VIPRES=`ip addr|grep 10.0.0.12|wc -l` if [ $VIPRES -eq 0 ] then ip addr add 10.0.0.12/32 dev lo label lo:12 route add -host 10.0.0.12 dev lo sleep 1 VIPRES=`ip addr|grep 10.0.0.12|wc -l` if [ $VIPRES -eq 0 ] then ip addr add 10.0.0.12/32 dev lo label lo:12 route add -host 10.0.0.12 dev lo sleep 1 VIPRES=`ip addr|grep 10.0.0.12|wc -l` if [ $VIPRES -eq 0 ] then action "ip addr add 10.0.0.12/32 ..." /bin/false exit 1 else action "ip addr add 10.0.0.12/32 ..." /bin/true fi else action "ip addr add 10.0.0.12/32 ..." /bin/true fi else action "ip addr add 10.0.0.12/32 is exist." fi echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce } function L_ipdel() { VIPRES=`ip addr|grep 10.0.0.12|wc -l` if [ $VIPRES -ne 0 ] then ip addr del 10.0.0.12/32 dev lo route del -host 10.0.0.12 dev lo sleep 1 VIPRES=`ip addr|grep 10.0.0.12|wc -l` if [ $VIPRES -ne 0 ] then action "ip addr del 10.0.0.12/32 ..." /bin/false exit 1 else action "ip addr del 10.0.0.12/32 ..." /bin/true fi else action "ip addr del 10.0.0.12/32 ..." /bin/true fi echo "0" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" > /proc/sys/net/ipv4/conf/lo/arp_announce echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce } #Step 2 function L_exec() { case "$1" in start) L_ipadd ;; stop) L_ipdel ;; status) VIPRES=`ip addr|grep 10.0.0.12|wc -l` sleep 1 if [ $VIPRES -ne 0 ] then echo "LVS Nginx is working" else echo "LVS Nginx is not working" fi ;; restart) VIPRES=`ip addr|grep 10.0.0.12|wc -l` if [ $VIPRES -ne 0 ] then L_ipdel sleep 1 L_ipadd else echo "ip 10.0.0.12 is not working" sleep 1 L_ipadd fi ;; *) echo "USAGE: $0 {start|stop|restart|status}" esac } 企业面试题26 【LVS备节点】模拟keepalved vrrp功能,监听主节点,如果主节点不可访问则备节点启动并配置LVS实现接管主节点的资源提供服务(提醒:注意ARP缓存) [root@lvs-lb01-05 scripts]# cat lvs.sh #!/bin/bash #Write by Bevin 2016 export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [ -f /etc/init.d/functions ] && source /etc/init.d/functions #Step 1 Instal ip_vs Ch_ipvs=`rpm -qa ipvsadm|wc -l` if [ $Ch_ipvs -eq 0 ] then yum install ipvsadm -y fi #Step 2 Functions VIP=10.0.0.12 V_TAIL=12 RIP=( 9 10 ) function L_LVS_VIP_RIP() { VIPRES=`ip addr|grep $VIP|wc -l` if [ $VIPRES -eq 0 ] then ip addr add $VIP/24 dev eth0 label eth0:$V_TAIL ipvsadm -C ipvsadm -A -t $VIP:80 -s rr for n in ${RIP[*]} do ipvsadm -a -t $VIP:80 -r 10.0.0.$n:80 -g done else ipvsadm -C ipvsadm -A -t $VIP:80 -s rr for n in ${RIP[*]} do ipvsadm -a -t $VIP:80 -r 10.0.0.$n:80 -g done fi } function L_check_vip() { VIPRES=`ip addr|grep $VIP|wc -l` if [ $VIPRES -eq 0 ] then L_LVS_VIP_RIP sleep 5 if [ $VIPRES -eq 0 ] then L_LVS_VIP_RIP sleep 5 if [ $VIPRES -eq 0 ] then echo "Warning: lb01: $VIP is down."|mail -s txbevin@sina.com exit 1 fi fi fi sleep 5 } function L_check_rip() { for n in ${RIP[*]} do CurlRes=`curl -I -s 10.0.0.$n|grep -E "200|301|302"|wc -l` if [ $CurlRes -ne 0 ] then RS=`ipvsadm -Ln|grep 10.0.0.$n|wc -l` if [ $RS -eq 0 ] then ipvsadm -a -t $VIP:80 -r 10.0.0.$n:80 fi else ipvsadm -d -t $VIP:80 -r 10.0.0.$n:80 mail -s "10.0.0.$n nginx is down at $(date +%F-%T)." txbevin@sina.com continue fi done sleep 5 } #Step 3 L_LVS_VIP_RIP while true do L_check_vip sleep 1 L_check_rip sleep 1 done 后面几道题如果大家会可以把答案发送给我 mail:new_oldboy@163.com ------------------- 企业面试题27 请用shell或Python编写一个正方形(oldboy_square.sh),接收用户输入的数字。 例如: [root@oldboy ~]# sh oldboy_square1.sh Please Enter a number:5 ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ [root@oldboy ~]# sh oldboy_square2.sh Please Enter a number:9 ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ ■■■■■■■■■ 企业面试题28 请用shell或Python编写一个等腰三角形(oldboy2_triangle.sh),接收用户输入的数字。 例如: [root@oldboy ~]# sh oldboy2_triangle.sh Please Enter a number:5 * *** ***** ******* ********* [root@oldboy ~]# sh oldboy2_triangle.sh Please Enter a number:8 * *** ***** ******* ********* *********** ************* *************** 企业面试题29 请用shell或Python编写一个画直角梯形程序(oldboy4.sh),接收用户输入的参数n,m 例如: [root@oldboy ~]# sh oldboy4.sh 4 6 **** ***** ****** 27,28,29三道题可以参考 http://oldboy.blog.51cto.com/2561410/1718607
本文出自 “老男孩linux培训” 请务必保留此出处http://oldboy.blog.51cto.com/2561410/1632876
没懂
[…] 老男孩Shell企业面试题30道 [答案] […]