linux必会的30道shell编程面试题及讲解

linux必会的30道shell编程面试题及讲解

1.通过ansibe批量给主机修改名称

#!/bin/bash

cat /etc/Hostname|\
while read line
do
 Host_IP="$(echo $line| awk '{print $1}')"
 Host_name="$(echo $line| awk '{print $2}')"
 ansible $Host_IP -m hostname -a "name=$Host_name"                                       
done

2.

使用for循环在/CSDN目录下通过随机小写10个字母加固定字符串CSDN批量创建10个html文件,名称例如为:

#coaolvajcq_CSDN.html  qnvuxvicni_CSDN.html  vioesjmcbu_CSDN.html
#gmkhrancxh_CSDN.html  tmdjormaxr_CSDN.html  wzewnojiwe_CSDN.html
  • 实现过程
#!/bin/bash
dir=/CSDN

for i in {1..10}
do
  # 第一种获取随机字符方法:date毫秒方式
  suiji=`date +%N%s|md5sum|cut -c1-10|tr '0-9' 'a-z'` 
  # 第二种获取随机字符方法:tr,不是a-z的都排除,不可以用cut命令,会卡住
  suiji=`tr -cd 'a-z' 

3.

将以上文件名中的CSDN全部改成blog(用for循环实现),并且html改成大写。

  • 实现过程
#!/bin/bash
# 方法1 变量子串功能
for i in `ls /CSDN`
do
    name=${i%%_*}
    mv  /CSDN/$i  /CSDN/${name}_CSDN.html
 done

# 方法2 rename功能
rename CSDN.html blog.HTML /CSDN/*.html 

# 方法3 命令拼接
ls /CSDN|sed -r 's#(^.*_)(.*)#mv \1CSDN.html \1blog.HTML#ge'

4.

批量创建10个系统帐号CSDN01-CSDN10并设置密码(密码为随机8位字符串)。

  • 实现过程
#!/bin/bash
for i in `seq -w 10`
do
        useradd CSDN$i >/dev/null
        #取8个字符串
        passwd=`cat /dev/urandom |head |md5sum | head -c8`
        #账户密码存放
        echo CSDN$i  $passwd  >> /CSDN.txt
        echo $passwd | passwd --stdin CSDN$i >/dev/null
        if [ $? -eq 0 ];then
                echo 用户CSDN${i}创建成功
        else
                echo 用户CSDN${i}创建失败
        fi
done

5.

写一个脚本,实现判断10.0.0.0/24网络里,当前在线用户的IP有哪些(方法有很多)

  • 实现过程
#!/bin/bash
. /etc/init.d/functions
for ip in 10.0.0.{1..254}
do
  ping -c1 -i1 -W1 $ip &>/dev/null
   # 次数 # 间隔 # 超时时间
  if [ $? -eq 0 ]
  then
      action "$ip is ok" /bin/true
  else
      action "$ip is failed" /bin/false
   fi
done

#第二种方法
#!/bin/bash
nmap -sn 10.0.0.0/24

6.

写一个脚本解决DOS生产案例提示:根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟。防火墙命令为:iptables -I INPUT -s 10.0.1.10 -j DROP。

[root@CSDN-m01 ~]# echo 3 119.121.180.245 
3 119.121.180.245 
[root@CSDN-m01 ~]# echo 3 119.121.180.245 |{ read count ip ; echo $count $ip ; } 
3 119.121.180.245 
#第一种
#!/bin/bash 1234567
netstat_file=/root/connect.txt 

awk -F'[ :]+' '/^tcp/ && $6!~/0.0.0.0/ {print $6}' /server/files/netstat.log |sort |uniq -c |sort - rn|head >$netstat_file
#1.取出每个ip的次数 

while read count ip 
do 
ip_drop_cnt=`iptables -nL |grep -wc "$ip"` 
#2.读取文件每一行并进行判断 

if [ $count -ge 5 ] && [ $ip_drop_cnt -eq 0 ] 
then iptables -I INPUT -s $ip -j DROP 
fi 
# 访问数量>=5 并且 防火墙中没有存在这个拒绝的规则 那么 iptables drop 

done<$netstat_file

#第二种方法
#!/bin/bash
log=/tmp/tmp.log
[ -f $log ] || touch $log
function add_iptables(){
    while read line
        do
          ip=`echo $line|awk '{print $2}'`
          count=`echo $line|wc -l`
            if [ $count -gt 100 ] && [ `iptables -L -n|grep "$ip"|wc -l` -lt 1 ]
             then
                iptables -I INPUT -s $ip -jDROP
                echo "$line isdropped" >>/tmp/droplist.log
            fi
        done<$log
}
function main(){
    while true
           do
             netstat -an|grep EST|awk '{print $(NF-1)}'|awk -F '[:]' '{print $1}'|sort|uniq -c >$log
             add_iptables
             sleep 180
    done
}
 
main

8.

如何实现对MySQL数据库进行分库备份,请用脚本实现

  • 实现过程
# 思路:先熟悉不进入数据库查看数据库中库的命令:mysql -uroot -pCSDN123 -e xxxxx然后尝试现将一个库进行备份操作,获取到所有库名称,然后进行循环操作
#!/bin/bash
for dbname in `mysql -e 'show databases;'|egrep -v 'schema|test|Database'`
  # 这三个名称是排除出去的,前两个目前不深入研究,不是自己创建的库,第三个是标题
do
  mysqldump -B $dbname |gzip >/root/$dbname.sql.gz
done


# 测试
gzip -d /root/$dbname.sql.gz

9.

如何实现对MySQL数据库进行分库加分表备份,请用脚本实现

#!/bin/bash
user=root
pass=CSDN123
mysql_cmd="mysql -u$user -p$pass"
for db in `$mysql_cmd -e "show databases;"|egrep -v "Database|schema"`
do
  for table in `$mysql_cmd -e "show tables from $db;"|egrep -v "Tables_in"`
  do
    mysqldump -u$user -p$pass $db $table|gzip >/backup/${db}_${table}.sql.gz
  done
done

10.

bash for循环打印下面这句话中字母数不大于6的单词(昆仑万维面试题)。II am CSDN teacher welcome to CSDN training class.

  • 实现过程
#!/bin/bash
str="I am CSDN teacher welcome to CSDN training class."
for zifu in $str
do
  if [ ${#zifu} -gt 6 ]
  then
      echo $zifu ${#zifu}
  fi
done


# 方法2 awk方式
echo "I am CSDN teacher welcome to CSDN training class."|awk '{for(i=1;i<=NF;i++)if(length($i) >6 )print $i}'

11.

开发shell脚本分别实现以脚本传参以及read读入的方式比较2个整数大小。以屏幕输出的方式提醒用户比较结果。注意:一共是开发2个脚本。当用脚本传参以及read读入的方式需要对变量是否为数字、并且传参个数做判断。

  • 实现过程
# 传参方式
#!/bin/bash
num1=$1
num2=$2

if [ $# -ne 2 ]
then
    echo "请输入两个参数"
    exit 2
fi

expr $num1 + $num2 + 666 &>/dev/null

if [ $? -eq 0 ]
then
    if [ $num1 -gt $num2 ]
    then
        echo "$num1 > $num2"
    elif [ $num1 -lt $num2 ]
    then
        echo "$num1 < $num2"
    else
        echo "$num1 = $num2"
    fi
else
    echo "请输入纯数字"
fi


# read方式
#!/bin/bash
read -p "请输入第一个数字" num1
read -p "请输入第二个数字" num2

expr $num1 + $num2 + 666 &>/dev/null

if [ $? -eq 0 ]
then
    if [ $num1 -gt $num2 ]
    then
        echo "$num1 > $num2"
    elif [ $num1 -lt $num2 ]
    then
        echo "$num1 < $num2"
    else
        echo "$num1 = $num2"
    fi
else
    echo "请输入纯数字"
fi

12.

打印选择菜单,一键安装Web服务:

[root@CSDNscripts]# 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、要对执行的脚本进行相关条件判断,例如:脚本是否存在,是否可执行

等。

#!/bin/bash
read -p "input your choose" command

lamp() {
           echo “startinstalling lamp.”
           [ -f /server/scripts/lamp.sh ] && [ -x /server/scripts/lamp.sh ]
           then
           sh /server/scripts/lamp.sh
           echo "lampis installed"
           else
           echo "can not running/server/scripts/lamp.sh"
           exit 1
}

lnmp() {
echo "startinstalling lnmp."
           [ -f /server/scripts/lnmp.sh ] && [ -x /server/scripts/lnmp.sh ]
           then
           sh /server/scripts/lnmp.sh
           then
           echo "lnmpis installed"
           else
           echo "can not running/server/scripts/lnmp.sh"
           exit 2
}

exit() {
exit 3
}

case $command in
           1)
           lamp
           ;
           2)
           lnmp
           ;
           3)
           exit
           ;
           *)
           echo "Input error"
           exit 4
esac

13.

1、监控web服务是否正常,不低于3种监控策略。

2、监控db服务是否正常,不低于3种监控策略。

要求间隔1分钟,持续监控。

1.监控web:
  1、curl方式
  2、wget
     进程和端口
     进程
     ps -ef 或 ps -C nginx -o pid comm --noheaders
     top:M 按内存使用率排序
          P 按cpu使用率排序(默认)
          q 退出
          z 开启/关闭颜色
          x 显示当前按照哪列排序
     top -p 46648
     top -b 进入批处理模式 可以搭配管道

[root@CSDN-m01 ~]# top -b -p 46649 | awk '/nginx/' 
46649 nginx 20 0 125496 3600 1056 S 0.0 0.2 0:00.01 nginx

[root@CSDN-m01 ~]# top -b -p 46649 | awk '/nginx/{print $1,$NF,$(NF-3)}' 
46649 nginx 0.0

     端口
     ss -lntup
     lsof -i
     nmap
     nginx状态模块
     stub_status;

2.监控db
  端口、进程、执行sql语句
----> curl和wget及相关参数
  • curl
- I:只显示响应头信息
- H: 修改请求头信息
- A: 指定浏览器(客户端代理)
- v: 显示详细请求和相应信息
- L: 跟随跳转
- s: 不显示头部统计信息,配合管道或-o
- o: 把curl的输出写入到指定文件
- u :指定用于登录的用户名和密码

curl -w "%{http_code}\n" -so /dev/null 10.0.0.61
  • wget
- O: 下载到指定文件中
- P: 下载到指定目录中(目录不存在自动创建)
-- debug: 显示请求和响应详细过程
- t: 最大尝试次数
- T: 超时时间
- q: 静默模式,不显示下载过程
-- spider: 爬虫,只访问不下载

14.(需要多加熟悉)

监控memcache服务是否正常,模拟用户(web客户端)检测。

使用nc命令加上set/get来模拟检测,以及监控响应时间及命中率。

[root@CSDN-m01 ~]# rpm -ql memcached /etc/sysconfig/memcached /usr/bin/memcached 123
▽root@CSDN-m01 ~]# vim /etc/sysconfig/memcached PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="64" OPTIONS="-l 172.16.1.61" 
[root@CSDN-m01 ~]# 
[root@CSDN-m01 ~]# systemctl restart memcached.service 
[root@CSDN-m01 ~]# ps -ef |grep mem 
memcach+ 51127 1 0 11:45 ? 00:00:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024 -l 172.16.1.61 root 51136 41363 0 11:45 pts/0 00:00:00 grep --color=auto mem 
[root@CSDN-m01 ~]# telnet 10.0.0.61 11211 Trying 10.0.0.61... telnet: connect to address 10.0.0.61: Connection refused 
[root@CSDN-m01 ~]# telnet 172.16.1.61 11211 Trying 172.16.1.61... Connected to 172.16.1.61. Escape character is '^]'. ERROR ERROR ERROR ^]telnet> Connection closed. 
#wordpress缓存数据缓存到memcached中: https://cn.wordpress.org/plugins/memcached/ 
#wordpress缓存数据缓存到redis中: https://cn.wordpress.org/plugins/redis-cache/ 
#wordpress会自动检查wp-content下面是否有object-cache.php 
使用memcached缓存wordpress博文数据 
修改:array('127.0.0.1','');为memcached服务器ip地址
[root@CSDN-m01 ~]# printf "stats\r\n"|nc 172.16.1.61 11211 |awk '/cmd_get/{get=$3}/get_hits/{hit=$3}END{print hit/get}' 
0.5

15.

面试及实战考试题:监控web站点目录(/var/html/www)下所有文件是否被恶意篡改(文件内容被改了),如果有就打印改动的文件名(发邮件),定时任务每3分钟执行一次。

#!/bin/bash
#file=`find /var/html/www -type f|xargs md5sum >/root/filemd5.txt` # 文件和MD5                                           
md5sum=`md5sum -c /root/filemd5.txt &>/root/webcheck.txt`
for i in `awk '{print $2}' /root/webcheck.txt`
do 

    if [ "$i" = "FAILED" ]
    then
        awk '/FAILED/{print $0}' /root/webcheck.txt
    else
        echo "ok"
    fi
done
  • 案例
  • 注意事项:
  • md5sum排除正常情况下会经常变动的目录:如日志目录
    • md5sum使用时间:在每次正常代码上线之后
  • 其他思路
    • 可使用find -mmin -5最近五分钟内修改的内容
# 找出目录下的文件
find /var/html/www -type f
# 生成指纹时排除经常变动的文件
find /var/html/www -type f | egrep -wv "cache|uploads" | xargs md5sum >/backup/www.md5
# 将文件及对应指纹输出到另一个文件中
find /var/html/www -type f | xargs md5sum >/root/www.md5
# 对指纹文件对应关系进行检查
md5sum -c /root/www.md5
# awk方式过滤出异常文件名输出到另一个文件中,用于发送邮件
md5sum --quiet -c /root/www.md5 | awk '/FAILED/{print $1}'
# 检查异常文件中是否存在内容,有则发送邮件
[ -s /web_eeor.txt ] && { mail -s "网站文件被修改" @qq.com /backup/www.md5

md5sum --quiet -c /root/www.md5 2>/dev/null | awk '/FAILED/{print $1}' >/web_error.txt

[ -s /web_eeor.txt ] && { mail -s "网站文件被修改" [email protected] 

16.

写网络服务独立进程模式下Rsync的系统启动脚本,例如:/etc/init.d/rsyncd {start|stop|restart}。
要求:
1.要使用系统函数库技巧。
2.要用函数,不能一坨SHI的方式。
3.可被chkconfig管理。

# 将此脚本放置到/etc/init.d下面,并添加执行权限
#########################################

#!/bin/bash
# chkconfig: 2345 99 98
# 2345:在2345下默认开机自启动
# 99:开机顺序
# 98:关机顺序
pid_file=/var/run/rsyncd.pid
command=$1
if [ "command" = "start" ]
then
    if [ -s "$pid_file" ]
    then
        echo "rsync已经是开启状态"
    else    
        rsync --daemon
    fi
elif [ "command" = "stop" ]
then
    if [ -s "$pid_file" ]
    then
        kill `cat /var/run/rsyncd.pid`
    else
        echo "rsync已经是关闭状态"
    fi
elif [ "command" = "restart" ]
then
    if [ -s "$pid_file" ]
    then
        kill `cat /var/run/rsyncd.pid`
        sleep 2 
        rsync --daemon
    else
        rsync --daemon
    fi
else
    echo "请输入正确的参数"


# chkconfig --add rsyncd

17.

好消息,班级学生外出企业项目实践机会(第6次)来了(本月中旬),但是,名额有限,队员限3人(班长带队)。

因此需要挑选学生,因此需要一个抓阄的程序:

要求:

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

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

  • 实现过程
dir="/jingxuan.txt"

check() {
read -p "请输入英文缩写:" suoxie
[[ $suoxie =~ [^a-Z]+ ]] && echo "[请输入正确格式]" && continue 
}

jilu() {
    num=$((RANDOM%99+1))
    count=`egrep -wc $num /root/$dir`
    if [ $count -eq 0 ]
    then
    echo 您的随机数:$num 已存入:/root$dir
    echo $suoxie $num >>/root$dir
else
    echo "数字重复" && continue
fi
}

main() {
check
jilu
}

while true
do
  main
done  

18.

已知下面的字符串是通过RANDOM随机数变量md5sum后,再截取一部分连续字符串的结果,请破解这些字符串对应的使用md5sum处理前的RANDOM对应的数字?

  • 实现过程
#!/bin/bash
null=(
2102929
00205d1c
a3da1677
1f6d12dd
) 
for num in {1..32767}
do
  num_md5=`echo "$num"|md5sum|cut -c1-8`
    #echo $num $num_md5
    for null in ${null[*]}
    do
      if [ "$num_md5" = "$null" ]
      then
          echo md5值:$null 原数字:$num
          break
      fi
    done
done             
  • 案例
# 将0-32767分别生成md5sum存入到文件中
# 过滤题目中的md5sum
for n in {0..32767}
do
  md5=`echo $n|md5sum`
  echo $md5 $n >>/root/md5.txt
done
  grep '题目中md5值' /root/md5.txt

19.

批量检查多个网站地址是否正常,要求:shell数组方法实现,检测策略尽量模拟用户访问思路

  • 实现过程
#!/bin/bash
#http://www.etiantian.org
#http://www.taobao.com
#http://CSDN.blog.51cto.com
#http://10.0.0.7 
. /etc/init.d/functions
url=( `cat /root/url.txt` )
# 将url添加到文件中

for n in ${url[*]}
do
  curl -q $n >/dev/null
  if [ $? -eq 0 ]
  then
      action "$n is ok" /bin/true
  else
      action "$n is failed" /bin/false
  fi
done

######亲自测试已成功,可以再次完善######

[root@m01 CSDN]# sh /server/scripts/url_shuzu_test.sh
http://www.etiantian.org/index.html is ok
http://www.etiantian.org/1.html is ok
http://post.etiantian.org/index.html is failed
http://mp3.etiantian.org/index.html is failed
http://www.etiantian.org/3.html is ok
http://post.etiantian.org/2.html is failed
  • 案例
#!/bin/bash 
url_list=( 
http://www.etiantian.org 
http://www.taobao.com oldray.ren 
http://CSDN.blog.51cto.com 
http://10.0.0.7 )
. /etc/init.d/functions 

#[[ ! $url =~ [0-Z]+\.(org|com|cn|xyz)$ ]] check() { url=$1

[[ $url =~ [0-Z]+\.(org|com|cn|xyz)$ || $url =~ [0-9.]+$ ]] || { 
echo "Usage: $0 $url" 
continue 
} 
}

chk_url() { 
url=$1 wget -q -t 3 -T 1 --spider $url 
if [ $? -eq 0 ] 
then
    action "$url is ok" /bin/true 
else
    action "$url is failed" /bin/false 
fi
}
main() { 
for url in ${url_list[*]} 
do 
    check $url 
    chk_url $url 
done 
}

main

20.

用shell处理以下内容

1、按单词出现频率降序排序!

2、按字母出现频率降序排序!

the squid project provides a number ofresources to assist users design,implement and support squid installations.Please browse the documentation and support sections for more infomation,byCSDN training.

str="the squid project provides a number ofresources to assist users design,implement and support squid installations.Please browse the documentation and support sections for more infomation,byCSDN training."
echo "$str"|grep "[a-Z]" -o|sort|uniq -c|sort -rnk1                     
echo
echo "$str"|egrep "[a-Z]+" -o|sort|uniq -c|sort -rnk1
  • 案例
# 方法1:egrep进行实现
egrep '[a-Z]+' -o /server/files/word.txt|sort |uniq -c |sort -rn

# 方法2:egrep+awk数组进行实现
egrep '[a-Z]+' -o /server/files/word.txt|awk 'arr[$0]++END{for(n in arr)print n,arr[n]}'|sort -rnk2

# 方法3:RS+awk数组进行实现
awk -vRS='[ .,\n]+' 'arr[$0]++END{for(n in arr)print n,arr[n]}' /server/files/word.txt
# 以空格、,、.、回车为换行符,遇到这些符号就换行,最后输出的就全部是单词了

# 方法4:awk -F进行实现
awk -F'[ .,]+' '{for(i=1;i<=NF;i++) array[$i]++ }END{for(n in array)print n,array[n]}' /server/files/word.txt
awk -F'[^a-zA-Z]+' '{for(i=1;i<=NF;i++) array[$i]++ }END{for(n in array)print n,array[n]}' /server/files/word.txt
#!/bin/bash
url_list=( 
10.0.0.61 
10.0.0.71 
10.0.0.81 
)
html=/usr/share/nginx/CSDN.html
true() {
sed -i '/$i/{s#failed#ok#g ; s#red#green#g}' $html
}
false() {
sed -i '/$i/{s#ok#failed#g ; s#green#red#g}' $html
}
#chk_url() {
#curl $i &>/dev/null
#}

main(){
for i in {$url_list[*]}
do
  curl $i &>/dev/null
  if [ $? -eq 0 ]
  then
      true
  else
      false
  fi
done
}

main

21.

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

#!/bin/bash
##############################################################
# File Name: /server/scripts/927.sh
# Version: V1.0
# Author: shan
# Organization: www.CSDNedu.com
##############################################################
#!/bin/bash
url_list=( 
10.0.0.51 
10.0.0.61 
10.0.0.71 
)
html=/usr/share/nginx/html/CSDN.html
true() {
sed -i "/$i/{s#failed#ok#g;s#red#green#g}" $html
}
false() {
sed -i "/$i/{s#ok#failed#g;s#green#red#g}" $html
}
main() {
    for i in ${url_list[*]}
do
    curl $i &>/dev/null
    if [ $? -eq 0 ]
    then
        true
    else
        false
    fi
done
}

main

你可能感兴趣的:(shell,shell)