兄弟连 企业shell笔试题 16-31

企业实践题16:
企业案例:写网络服务独立进程模式下rsync的系统启动脚本

例如:/etc/init.d/rsyncd{start|stop|restart} 。
要求:
1.要使用系统函数库技巧。
2.要用函数,不能一坨SHI的方式。
3.可被chkconfig管理。

脚本1:自己写的

 

#!/bin/bash

pidfile="/var/run/rsyncd.pid"
result=`ps aux|grep  'rsync --daemon --config=*'|grep -v grep`

Rstatus(){
if [ "$result"X = X ];then
 echo "rsyncd is not running !"
else
 echo "rsyncd is running"
fi
}


Rstart(){
if [ "$result"X == X ];then
 /usr/bin/rsync --daemon --config=/etc/rsyncd/rsyncd.conf
 echo "rsync service start.......OK"
else
 echo "rsyncd is running"
fi
}

Rstop(){
if [ "$result"X == X ];then
   echo "rsync service is down !"
   exit 1
else
 kill -9 $(cat $pidfile)
 Rstatus2=`ps aux|grep  'rsync --daemon --config=*'|grep -v grep`
 if [ "$Rstatus2"X = X ];then
   rm -f $pidfile
   echo "rsync service stop.......OK"
 fi
fi
}


Rrestart(){
if [ "$result"X != X ];then
 Rstop
 /usr/bin/rsync --daemon --config=/etc/rsyncd/rsyncd.conf
 echo "rsync service start.......OK"
else
 echo "rsync service is down !"
fi
}

case $1 in
"start" )
 Rstart
;;
"stop" )
 Rstop
;;
"restart" )
 Rrestart
;;
"status" )
 Rstatus
;;
* )
echo "argument is start|stop|status|restart"
;;
esac

 

脚本2:网上找的

#!/bin/bash 
#this script for start|stop rsync daemon service 

status1=$(ps -ef | egrep "rsync --daemon.*rsyncd.conf" | grep -v 'grep') 
pidfile="/var/run/rsyncd.pid" 
start_rsync="rsync --daemon --config=/etc/rsyncd/rsyncd.conf" 
  
                    #start rsync
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 
} 
  
 
                  #stop rsync
function rsyncstop() { 
    if [ "${status1}X" != "X" ];then 
        kill -9 $(cat $pidfile)                               #读取并结束 进程 pid号
        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 
} 
  
              #status 
function rsyncstatus() { 
    if [ "${status1}X" != "X" ];then 
        echo "rsync service is running !"   
    else
         echo "rsync service is not running !"  
    fi 
} 
           #restart
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:

需要一个抓阄的程序:

要求:

1、执行脚本后,想去的同学输入英文名字全拼,产生随机数01-99之间的数字,数字越大就去参加项目实践,前面已经抓到的数字,下次不能在出现相同数字。

2、第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入

重点语句分析:
产生01-99随机数  
 我开始使用的是  echo $RANDOM | head -c 2   这个语句只能产生 10-99
 修改后为 echo $(($RANDOM%100))

用嵌套的两个while 来完成接收用户名和 生成数字-判断数字重重功能

#!/bin/bash

namelist=/tmp/name.txt
#判断数字是否重复
judgeNum(){
grep -w $1 $namelist
if [ "$?" -eq 0 ];then
 a=1
else
 a=0
fi
}

while  read -p "please input your name:" name
do
 a=1
 while [ $a -eq 1 ]  #数字不重复就跳出第二个while ,重复就再生成一个
  do
   num=`echo $(($RANDOM%100+1))`
   judgeNum $num
  done
 echo "$name:$num" |  tee -a $namelist  #结果显示到屏幕 并 追加到文件中
done


 

 

 企业实践题18:

已知下面的字符串是通过RANDOM随机数变量md5sum|cut-c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字?

21029299

00205d1c

a3da1677

1f6d12dd

890684b

重点语句分析:
我直接用 爆破法了
查看一个变量是否包含在 数组内两个方法
1. 
if [[ ${array[*]} =~ $variable ]]
2. echo ${array[*]} | grep -w "xxx"

 

#!/bin/bash

array=(21029299 00205d1c a3da1677 1f6d12dd 890684ba)
count=0

for i in `seq 0 32767`
do
variable=`echo $i | md5sum | cut -c 1-8`
 if [[  ${array[*]} =~ $variable ]];then
  let count++
  echo "$count: $i ==>> $variable"
 fi
[ $count -eq 5 ] && exit 
done

运行结果

# bash 18old.sh
1: 1346 ==>> 00205d1c
2: 7041 ==>> 1f6d12dd
3: 10082 ==>> 890684ba
4: 25345 ==>> a3da1677
5: 25667 ==>> 21029299

 

 

企业实践题19:

批量检查多个网站地址是否正常 

    要求:shell数组方法实现,检测策略尽量模拟用户访问思路

    http://www.etiantian.org

    http://www.taobao.com

    http://oldboy.blog.51cto.com

    http://10.0.0.7 
重点语句分析:

验证网站的可行性两种方法
wget -T 5 -t 2 --spider 
http_code=`curl -m 5 -s -o /dev/null -w %{http_code} 

#!/bin/bash

[ -f /etc/init.d/functions ] && source /etc/init.d/functions

array=(
http://www.163.com
http://www.taobao.com
http://oldboy.blog.51cto.com
http://10.0.0.7
)

wait(){
echo -n "wait"
for((a=1;a<=3;a++))
do
 echo -n "."
 sleep 1
done
}

check_url(){
wget -T 5 -t 2 --spider $1 &>/dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ];then
 action "check $1" /bin/true
else
 action "check $1" /bin/false
fi
return $RETVAL
}

main(){
for((i=0;i< ${#array[*]};i++))
do
 wait
 check_url ${array[i]}
done
}

main

运行结果:

# bash 19old.sh
wait...check http://www.163.com [ OK ]
wait...check http://www.taobao.com [FAILED]
wait...check http://oldboy.blog.51cto.com [ OK ]
wait...check http://10.0.0.7

淘宝访问失败是因为 ssl 验证

 

 

企业实践题20:

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

重点语句分析:
单词排序   先把这一句话  按空格符 生成一个单词一行,然后再排序

1.使用for循环将这一变量(句话)   再用 sort uniq sort  排序
2.使用 sed 's/ /\n/g' | sort | uniq -c | sort -r
3.使用 tr ' ' '\n'|sort|uniq -c |sort -r

字母排序 
将字符串变量while read 按行输入,然后截取cut -c 每一个字符 存入文件(一行一个字符)
sort进行排序统计

#!/bin/bash
a="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"

word=/tmp/word.txt

word_sort(){
for i in `echo $a`
do
echo $i >> $word
done
cat $word|sort|uniq -c|sort -rn
}

letter_sort(){
echo $a |
while read line
do
 for i in `seq 1 ${#line}`
 do
  echo $line |cut -c "$i" >> $word
 done
done
cat $word |sort|uniq -c|sort -rn
}

main(){


[ -f $word ] && rm -f $word
echo "word sort input 1"
echo "letter sort input 2"
read num


case $num in
"1")
word_sort
;;
"2")
letter_sort
;;
*)
echo "please input 1 or 2"
esac
}


main

 

 

企业实践题21:

输出正方形、等腰三角形、直角梯形

1.输出正方形
这里使用+  或者 ■   这两种符号实现
加号的宽度应该乘以2  长宽才相等

#!/bin/bash
echo -n "please input a number:"
read a
let b=a*2
for((i=1;i<=$a;i++))
do
 printf "%-"$b"s\n" "+"|sed 's/ /+/g'
done

 其次使用两个for循环嵌套 来实现

#!/bin/bash

echo "input a number"
read num

let num2=num*2
for((a=1;a<="$num";a++))
do
 echo -e "\n"
 for((b=1;b<="$num2";b++))
 do
  echo -n +
 done
done

 

2.输出直角梯形

#!/bin/bash

echo -n "please input a number:"
read a
for((i=1;i<=$a;i++))
do
 printf "%-"$i"s\n" "+"|sed 's/ /+/g'
done
#!/bin/bash

echo "input a number"
read num

#let num2=num*2
for((a=1;a<="$num";a++))
do
 echo -e "\n"
 for((b=1;b<=a;b++))
 do
  echo -n "+"
 done
done

 

3.输出等腰梯形
用四个for循环来构造,第一个for确定每一行,第二个for 打印每行前段空格,第三个for输出+,第四个for打印每行末尾空格

 

#!/bin/bash

echo "please a number"
read num

let sum=num*2+1

for((a=1;a<=num;a++))
do

 for((b=1;b<=$[(sum-2*a-1)/2];b++))
 do
  echo -n " "
 done

 for((b=1;b<=$[2*a-1];b++))
 do
  echo -n "+"
 done

 for((b=1;b<=$[(sum-2*a-1)/2];b++))
 do
  echo -n " "
 done

 echo -e "\n"
done

 

 

 

企业实践题22:

开发通过web界面展示监控Nginx代理节点状态,效果图如下。

思路:
首先新建一个html页面(如上图),然后编写shell脚本检测机器状态,
检测结果直接修改html文件,up-》down。

我这里简单写了一个脚本:

#!/bin/bash

html_file=/var/www/html/status.html
array=(
192.168.0.104
)

check(){
array[0]=`netstat -anptl | grep "httpd"|wc -l`
}

output(){
if [ ${array[0]} -eq 0 ];then
  echo '<td align="center" bgcolor="green"><font size="15">OK!</font></td>' > $html_file
elif [ ${array[0]} -eq 1 ];then
  echo '<td align="center" bgcolor="green"><font size="15">OK!</font></td>' > $html_file
fi
}

while true
do
check
output
sleep 20
done

 

网上找到一个比较好的脚本

#!/bin/bash
#Author: Stanley Wang
#mail: 
#Version: 1.0
#Description: This is a script for nginx proxy health check.
#
###def vars##########
RS=(
  172.16.1.191
  172.16.1.192
)
PORT=80
html_file="/var/html/www/index.html"
declare -a RSTATUS
###main##############
function checkrs(){
  local I=0
  for ((I=0;I<${#RS[*]};I++))
  do
    RSTATUS[$I]=`nmap ${RS[$I]} -p $PORT|grep "open"|wc -l`
  done
}
function output(){
    if [ ${RSTATUS[0]} -eq 0 ];then
      #echo "${RS[$i]} is down!"
      sed -i '22 s/.*/<td align="center" bgcolor="red"><font size="15">Down!<\/font><\/td>/g' $html_file
    elif [ ${RSTATUS[0]} -eq 1 ];then
      #echo "${RS[$i]} is OK!"
      sed -i '22 s/.*/<td align="center" bgcolor="green"><font size="15">OK!<\/font><\/td>/g' $html_file
    fi
    if [ ${RSTATUS[1]} -eq 0 ];then
      #echo "${RS[$i]} is down!"
      sed -i '28 s/.*/<td align="center" bgcolor="red"><font size="15">Down!<\/font><\/td>/g' $html_file
    elif [ ${RSTATUS[1]} -eq 1 ];then
      #echo "${RS[$i]} is OK!"
      sed -i '28 s/.*/<td align="center" bgcolor="green"><font size="15">OK!<\/font><\/td>/g' $html_file
    fi
}
while true
do
  checkrs
  output
sleep 2
done
View Code

 

 

企业实践题23:
【LVS主节点】手工开发ipvsadm管理lvs的脚本ip_vs

 实现:/etc/init.d/lvs {start|stop|restart}

说明为了简化脚本便于理解,这里使用LVS 中的     DR工作模式 + rr轮询模式  ,不使用keepalive
机器ip如下:

vip 10.0.0.90
Director server ip 10.0.0.54
Real server 10.0.0.56 10.0.0.57

 

#/bin/bash
[ $UID -ne 0 ] && echo "please use root run" && exit 22
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
vip=10.0.0.90
vip_netmask=10.0.0.90/24
RealServer=(
10.0.0.56
10.0.0.57
)

start(){
ip addr show|grep "$vip" &>/dev/null
#判断网卡上 vip 是否存在,不存在添加
if [ "$?" -ne 0 ];then
   ip addr add "$vip_netmask" dev ens32
   action "ip address add vip "$vip_netmask"" /bin/true
else
   echo "ip address vip $vip_netmask already exists"
fi
#判断ipvsadm中 vip是否存在,不存在则添加 lvs_table=`ipvsadm -ln|grep "$vip"|wc -l` if [ "$lvs_table" -eq 1 ];then echo "ipvsadm vip already exist" else ipvsadm -A -t "$vip":80 -s rr action "ipvsadm add vip $vip" /bin/true fi
#判断ipvsadm中 real server是否存在,不存在则添加
for ip in ${RealServer[*]}
do
 rs_num=`ipvsadm -ln | grep "$ip"|wc -l`
 if [ $rs_num -eq 1 ];then
   echo "real server $ip already exists"
 else
   ipvsadm -a -t "$vip":80 -r $ip -g
   action "ipvsadm add real server $ip" /bin/true
 fi
done
}

stop(){
ip addr show|grep $vip &>/dev/null
if [ "$?" -ne 0 ];then
 echo "ip address vip $vip is not exist"
else
 ip addr del $vip_netmask dev ens32
  action "ip address delete vip $vip" /bin/true
fi

ipvsadm -C && action "clear all lvs table." /bin/true
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
*)
echo "please input {start|stop|restart}"
esac

 



 企业实践题24:

【LVS主节点】模拟keepalived健康检查功能管理LVS节点,

当节点挂掉(检测2次,间隔2秒)从服务器池中剔除,好了(检测2次,间隔2秒)加进来

提示:利用ipvsadm命令实现添加和减少LVS节点。

机器ip如下:

 

vip 10.0.0.90
Director server ip 10.0.0.54
Real server 10.0.0.56 10.0.0.57

说明:这道题目是 编写脚本 检查 Real server 服务器的状态,失效的则使用命令ipvsadm 踢出 ,状态恢复则用 ipvsadm 重新加入
使用两个函数  ,函数判断如下
status_del()函数

ipvsadm中是否存在   两次检测状态 操作
×× 从ipvsadm中删除
√× 或 √√ echo running
不在   ×× echo down

 

 

 

 

 

 

 

status_add() 函数

ipvsadm 中不存在     两次检测状态√√       向ipvsadm中添加这个real server ip

#!/bin/bash
[ $UID -ne 0 ] && echo "please use root run" && exit 22
[ -f /etc/init.d/functions ] && . /etc/init.d/functions

#定义 vip 和real server ip

vip=10.0.0.90
vip_netmask=10.0.0.90/24
RealServer=(
10.0.0.56
10.0.0.57
)


status_del(){
for Rs_ip in ${RealServer[*]}
do
 error=0   #定义检测失败次数
#进行两次检测 
for((i=1;i<=2;i++))
 do
   x=` nmap -p 80 $Rs_ip | grep 'open' | wc -l`
   if [ "$x" -eq 0 ];then
     let error+=1
   fi
   sleep 2
 done
#检查real主机ip 是否在 ipvsadm列表中
vs_ip=`ipvsadm -ln|grep $Rs_ip | wc -l`
#两次检测失败,而且real ip存在ipvsadm列表中,执行向ipvsadm中添加命令
if [ $error -eq 2 -a $vs_ip -ne 0 ];then
     ipvsadm -d -t "$vip":80 -r "$Rs_ip":80
     echo "Real server $Rs_ip is down,delete it"
#两次检测失败,而且不存在ipvsadm列表中,输出 down elif [ $error -eq 2 -a $vs_ip -eq 0 ];then echo "Real server $Rs_ip is down"
#检测失败次数为0或者1,列表中存在,输出 running elif [ $error -ne 2 -a $vs_ip -ne 0 ];then echo "Real server $Rs_ip is running" fi done } status_add(){ for Rs_ip in ${RealServer[*]} do bingo=0 for((i=1;i<=2;i++)) do x=` nmap -p 80 $Rs_ip | grep 'open' | wc -l` if [ "$x" -eq 1 ];then let bingo+=1 fi sleep 2 done vs_ip=`ipvsadm -ln|grep $Rs_ip | wc -l`
#两次检测成功,real ip不在ipvsadm中,执行向ipvsadm 添加ip 命令
if [ $bingo -eq 2 -a $vs_ip -eq 0 ];then ipvsadm -a -t "$vip":80 -r "$Rs_ip":80 echo "Real server $Rs_ip is recover,add it" fi done } main(){ while true do status_del sleep 10 status_add sleep 10 done } main

 

 

企业实践题25:

【LVS客户端节点】开发LVS客户端设置VIP以及抑制ARP的管理脚本

    实现:/etc/init.d/lvsclient {start|stop|restart}
说明:在real server 上 实现脚本开关命令

机器ip如下:

 

vip 10.0.0.90
Director server ip 10.0.0.54
Real server 10.0.0.56 10.0.0.57

#!/bin/bash
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
vip=10.0.0.90
vip_netmask=10.0.0.90/32
RealServer=10.0.0.56

start(){
# lo网卡上没有vip 则添加 ip addr show
|grep "$vip" &>/dev/null if [ "$?" -ne 0 ];then ip addr add "$vip_netmask" dev lo fi echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
#检测lo是否添加上vip ip addr show
|grep "$vip" &>/dev/null if [ "$?" -eq 0 ];then action "ip address add vip $vip_netmask ,lvs_client start" /bin/true else action "can't add vip $vip_netmask " /bin/false fi } stop(){
#lo网卡上有 vip 则删掉 ip addr show
|grep "$vip" &>/dev/null if [ "$?" -eq 0 ];then ip addr del "$vip_netmask" dev lo fi echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce
#检测删除结果 ip addr show
|grep "$vip" &>/dev/null if [ "$?" -ne 0 ];then action "ip address del vip $vip_netmask ,lvs_client stop" /bin/true else action "can't del vip $vip_netmask " /bin/false fi } case $1 in start) start ;; stop) stop ;; restart) stop sleep 1 start ;; *) echo "USAGE: $0 {start|stop|restart|status}" esac

 

 

企业实践题26:

【LVS备节点】模拟keepalved vrrp功能,监听主节点,如果主节点不可访问则备节点启动并配置LVS实现接管主节点的资源提供服务(提醒:注意ARP缓存) 

说明:编写的这个脚本运行在LVS的 备用DS上,监听主节点 ,一旦主节点发生故障,立即接管(这里不考虑,主节点恢复后 主备的抢占问题),并退出监控
这里用到了 脚本23的 start() 函数

机器ip如下:

vip 10.0.0.90
Director server ip 10.0.0.54(主) 10.0.0.55(备)
Real server 10.0.0.56 10.0.0.57

#!/bin/bash

[ -f /etc/init.d/functions ] && . /etc/init.d/functions

vip=10.0.0.90
RealServer=(10.0.0.56 10.0.0.57)
gateway=10.0.0.254
dev=ens32

start(){
ip addr show|grep "$vip" &>/dev/null
if [ "$?" -ne 0 ];then
   ip addr add "$vip"/24 dev $dev
   arping -I $dev -c 3 -s $vip $gateway &>/dev/null
   action "ip address add vip "$vip"" /bin/true
else
   echo "ip address vip $vip already exists"
fi

lvs_table=`ipvsadm -ln|grep "$vip"|wc -l`

if [ "$lvs_table" -eq 1  ];then
   echo "ipvsadm vip already exist"
else
   ipvsadm -A -t "$vip":80 -s rr
   action "ipvsadm add vip $vip" /bin/true
fi

for ip in ${RealServer[*]}
do
 rs_num=`ipvsadm -ln | grep "$ip"|wc -l`
 if [ $rs_num -eq 1 ];then
   echo "real server $ip already exists"
 else
   ipvsadm -a -t "$vip":80 -r $ip -g
   action "ipvsadm add real server $ip" /bin/true
 fi
done
echo "master is stop ,slave have running"
exit 10
}

check_lvs(){
ping -c 2 $vip &>/dev/null
RETVAL=$?
if [ $RETVAL -ne 0 ];then
  start
else
  echo 'lvs master is good'
fi
}

main(){
while true
do
  check_lvs
  sleep 10
done
}

main

 

 

企业实践题27:
请用shell或Python编写一个正方形(oldboy_square.sh),接收用户输入的数字。
此题与脚本21题 相同,略过

 

企业实践题28:
请用shell或Python编写一个等腰三角形(oldboy2_triangle.sh),接收用户输入的数字
此题与脚本21题 相同,略过

 

企业实践题29:
请用shell或Python编写一个等腰三角形(oldboy2_triangle.sh),接收用户输入的数字
此题与脚本21题 相同,略过

 

posted @ 2017-12-04 22:57  乌托邦眺望  阅读(619)  评论(0编辑  收藏  举报