当前位置: 代码迷 >> 综合 >> Linux系统运维之常见的shel企业面试题
  详细解决方案

Linux系统运维之常见的shel企业面试题

热度:26   发布时间:2024-03-10 01:47:26.0

目录

  • 前言
  • 一、题目
    • 1、批量生成文件名
    • 2、批量更改文件名
    • 3、批量创建用户
    • 4、扫描网段内存活的IP
    • 5、解决DOS攻击
    • 6、数据库备份(库备份、表备份)
    • 7、筛选合适长度的单词
    • 8、比较两个整数的大小
    • 8、打印菜单选项
    • 9、网站入侵检测
    • 10、nginx启动脚本
    • 11、抓阄脚本
    • 12、破解RANDON随机数
    • 13、批量查看多个网址是否是正常
    • 14、字符串去重排序
    • 15 、web以及mysql服务异常监测

前言

本篇文章借鉴《跟老男孩学Linux运维—shell编程实战》一书,下面文章题目全部出自此书,感兴趣的小伙伴可以购买阅读,很适合入门。

一、题目

1、批量生成文件名

使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy

注意随机数生成的方法:1、openssl rand -base64 + (生成的随机数位数) 2、$RAND  (范围是0-32767) 【可以通过md5sum进行加密】3、date +%s%N4、head /dev/urandomIcksum#脚本实现
[root@any /server/scripts/mianshiti]#cat 1_piliangwenjian.sh 
#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-26 22:39:25
#Name:1_piliangwenjian.sh
#Version:VI.0
#Discription:To 
#######################################################
[ -d /opt ] || mkdir /opt
for n in {
    1..10}
dorand=`openssl rand -base64 30|sed "s#[^a-z]##g"|cut -c 2-10`touch /opt/any_${
    rand}.html
done

2、批量更改文件名

将题目一所得文件名中的oldboy字符串全部改成oldgirl (最好用for循环实现),并且将扩展名html全部改成大写。

[root@any /server/scripts/mianshiti]#cat 2_gaiming.sh 
#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-26 22:56:00
#Name:2_gaiming.sh
#Version:VI.0
#Discription:To 
########################################################第一种方法:renamea专业的名字更改命令更改
rename (原名) (将要改成的名称) (文件)
rename "any" "ANY" /opt/*                                       
rename "html" "HTML" /opt/*                                 # =========================================
#第二种方法:
dir=/opt/
if [ -d $dir ] 
thencd $dirfor n in `ls`doname=`echo $n|awk -F "[_.]" '{print "ANY_"$2".HTML"}'`mv $n $namedone
elseexit 1
fi
# =========================================#第三种方法:awk拼接
ls|awk -F "[_.]" '{print "mv",$0,"ANY_"$2".HTML"}'|bash

3、批量创建用户

批量创建10个系统账号any01-10并设置密码(密码为随机数,要求是字符和数字等的混合)。

[root@any /server/scripts/mianshiti]#cat 3_useradd.sh 
#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-27 08:53:59
#Name:3_useradd.sh
#Version:VI.0
#Discription:To 
#######################################################
. /etc/init.d/functions          #引用库函数
for n in {
    1..10}
dorand=`openssl rand -base64 30|sed "s#[^a-z1-9]##g"|cut -c 2-11`id any$n &>/dev/nullif [ $? -ne 0 ]thenuseradd any$necho "$rand"|passwd --stdin $n 2>/dev/null   #指定随机密码echo -e "any$n\t$rand" >>/tmp/user.txt       #注意要输出密码action "user any$n is exist!" /bin/true     #引用库函数下面的action函数elseaction "user any$n is already exist!"  /bin/falsecontinuefi
done

4、扫描网段内存活的IP

写一个Shell脚本,判断10.0.0.0/24网络里,当前在线的IP有哪些?

方法一:
[root@any /server/scripts/mianshiti]#cat 4_wangduan.sh 
#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-27 10:38:36
#Name:4_wangduan.sh
#Version:VI.0
#Discription:To 
#######################################################
. /etc/init.d/functions
cmd='ping -c 2 -W 2'   #-c 尝试次数,-W超时时间
ip='10.0.0.'
for n in {
    1..255}
do$cmd ${ip}$n &>/dev/null if [ $? -eq 0 ]thenaction "Url ${ip}$n is ok" /bin/trueelseaction "Url ${ip}$n is error" /bin/falsefi
done方法二:
#使用nmap命令
nmap - 网络探测工具和安全/端口扫描器-sP:进行ping扫描 (主机发现),然后打印出对扫描做出响应的那些主机。 没有进一步的测试(如端口扫描或者操作系统探测)。-sS:TCP SYN扫描,只扫描不进行连接,在一个没有入侵防火墙的快速网络上,每秒钟可以扫描数千个端口。CMD="nmap -sP "
Ip="10.0.0.0/24"
CMD2 ="nmap -sS"
$CMD $Ip|awk '/Nmap scan report for/ {print $NF}'

5、解决DOS攻击

写一个Shell脚本以解决DOS攻击生产的问题。
请根据Web日志或网络连接数,监控当某个IP并发连接数或短时内PV达到100(读者可根据实际情况来设定)时,即调用防火墙命令封掉对应的IP。防火墙命令为:
“iptables -I INPUT -s IP -j DROP” (IP 为要封的地址)。

分析:
先分析Web日志,可以每分钟或每小时分析一次,这里给出按小时处理的方法。可以将日志按小时进行分割,分成不同的文件,根据分析结果把PV数高的单IP封掉。例如,每小时单IP的PV数超过500,则即刻封掉,这里简单地把日志的每一行近似看作一个PV,实际工作中需要计算实际页面的数量,而不是请求页面元素的数量,另外,很多公司都是以NAT形式上网的,因此每小时单IP的PV数超过多少就会被封掉,还要根据具体的情况具体分析,本题仅给出一个实现的案例,读者使用时需要考虑自身网站的业务去使用。

iptables -L -n:查看ip的访问情况
uniq  用于报告或者忽略重复行-c:count,在该行显示重复连接的次数-d:仅显示重复出现的行列-u:仅显示出现一次的行列sort    对文本文件内容进行排序,可以针对文件的内容按照单位进行排序-r:以相反的顺序来排序-b:忽略每行前面开始出现的空行-c:检查文件是否已经按照顺序排序-n:按照数值大小排序-o:将排序后的内容结果指定到文件当中-t:分个字符,指定排序时所用的栏位分隔字符[root@any /server/scripts]#cat DDOS.sh 
#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-24 16:17:33
#Name:DDOS.sh
#Version:VI.0
#Discription:To 
#######################################################
#网站监测
abc(){
    
#对文件进行处理,把外网访问的所有的ip地址进行分类按,访问次数进行排名,导入到一个临时的文件,然后对这个临时文件进行提取ip和次数
awk -F "[ :]+" /ESTABLSHED/{
    print $(NF-3)} /tmp/netstat.log|sort|uniq -c|sort -rn|head -10 >/tmp/ip.log
while read line
doip=`echo $line|awk '{print $2}'`count=`echo $line|awk '{print $1}'`if [ $count -gt 10 ] && [`iptables -nL|grep "$ip"|wc -l` -lt 1]thenecho "$ip is degrous"iptables -I INPUT -s $ip -j DROP     #>>>封杀ipecho "$ip is dropped" >>/tmp/droplist_$(date +%F).log    #把处理日志导出,方便检查else echo "$ip is safy"fi
done </tmp/ip.log
}
main(){
    
while true
doabcsleep 5
done
}
main

6、数据库备份(库备份、表备份)

分库备份:
PATH="/application/mysql/bin/mysqld:$PATH"
backup='/tmp/mysql'
master='root'
passwd='any123'
#进入到数据库中并且打开库列表
mysql=`$PATH -u${
     master} -p${
     passwd} -e show databases|sed "1d"|egrep -v "_achema"`
for n in $mysql
domysqldump -u$master -p$passwd -B $n 2>/devnull|gzip >${backup}/${date+%T%F}.sql.gz
done每个库里面的每一个表备份:
backup='/tmp/mysql/'
master='root'
passwd='any123'
database=`mysql -u${
     master} -p${
     passwd} -e "show databases;" 2>/dev/null|sed "1d"|egrep -v "_schema"`
for n in $database
domkdir -p ${backup}${n}_$(date +%F)tables=`mysql -u$master -p$passwd -e "show tables from $n;"|sed "1d"|egrep -v "mysql|schema"` #删选表for tab in $tables         #双重for循环,每个库进入库里面列表当中domysqldump -u$master -p$passwd -B $tab 2>/devnull|gzip >${backup}${n}_$(date +%F)/${n}_${table}.sql.gz     #备份库下面的所有表done
done

7、筛选合适长度的单词

给一段字符串:I am oldboy teacher welcome to oldboy training class,从中筛选长度不大于6的单词

#运用数组
arr=(I am oldboy teacher welcome to oldboy training class)
for n in ${#arr[*]}
doif [ ${#arr[n]} -le 6 ]thenecho "${arr[n]}"fi
done

8、比较两个整数的大小

输入两个整数,并且输出大小的比较

usage(){
    echo "请正确输入!!"exit
}
compare(){
    read -p "请输入两个数:" a bexpr $a + $b + 10 &>/dev/nullif [ $# -ne 2 -a $? -ne 0 ]thenusageelseif [ $a -gt $b ]thenecho 'a>b'elif [ $a -lt $b ]then  echo 'a<b'elseecho 'a=b'fifi}

8、打印菜单选项

把选项列出来,然后根据需要,选择合适的选项

cat <END1.[蔡徐坤]2.[詹姆斯]3.[科比]4.[韦德]5.[exit]
END
while true
doread -p "Plaese input the num:" ncase a in $ndo 1)echo "you love 蔡徐坤!";;2)echo "you love 詹姆斯!";;3)echo "you love 科比!";;4)echo "you love 韦德!";;5)echo "you are SB!"exit;;done 
done

9、网站入侵检测

分析:
一、篡改1、恶意篡改,顾名思义就是未经过允许修改网页内容2、文件的大小,内容,修改时间会变化
二、采用md5sum指纹校验方法,建立进本的指纹库,以用来与源文件进行比对数据
三、检测文件内容和数量的变化1、用md5sum来检测文件内容的变化:md5sum -c -quiet2、因为md5sum无法检测新的文件,所以用diff来比对检测#先给网站下面的所有的目录文件进行指纹的索取,索取之后,如果网站下面的文件内容有篡改,则用"md5sum -c " 命令就会检测出来
[root@web02 /server/scripts]#find =/application/nginx/html -type f|xargs md5sum >$zhiwen 
#先复制源文件到指定目录之下,相当于先备份,然后如果源文件被篡改,则把备份文件与源文件进行对比之后就会查出被篡改的文件
[root@web02 /server/scripts]#find =/application/nginx/html -type f >$wenjian_yuan 
[root@web02 /server/scripts]#cat check_web.sh 
web_dir=/application/nginx/html
zhiwen=/opt/zhiwen.db.ori
wenjian_yuan=/opt/wenjian.db.ori
wenjian_check=/opt/wenjian.db.ori_bak
#错误文件查看目录
error=/opt/web_error.log  
[ -e $web_dir ] || exit
echo '#md5sum -c --quiet /opt/zhiwen.db.ori' >$error
md5sum -c --quiet $zhiwen &>>$error
if [ $? -ne 0 ]
thenecho 'error! Please check the error file in /opt/web_error.log!'echo "find $web_dir -type f >$wenjian_check" >>$errorfind $web_dir -type f >$wenjian_check diff /opt/wenjian.db* &>/dev/nullif [ $? -ne 0 ]thenecho 'error! Please check the error file in /opt/web_error.log!'fi
elseecho 'file is ok!'
fi

10、nginx启动脚本

CentOS 6版本下的自启动:

CentOS6实现chconfig管理注意
chk --list             #查看服务
chkconfig [服务] off   #关闭服务
chkconfig [服务] on    #开启服务
自启动运行脚本开头必须要加上:
chkconfig:2345 90 60 (2345是默认运行级别同时处理;90:开始启动服务顺序;60:停止关闭服务顺序;都可以自定义)如下所示启动脚本文件:
[root@any ~]#cat /etc/init.d/nginx #nginx启动脚本必须要在/etc/init.d/目录下面
#!/bin/bash
#chkconfig:2345 90 60 #必须要加,可以自定义启动和关闭的顺序
#decription:nginx #可加可不加function usage(){
    echo "Usage:$0 {start|restart|stop|reload}"exit 0
}
function start(){
    /application/nginx/sbin/nginxsleep 2
if [ `netstat -lntup|grep nginx|wc -l` -ne 0 ]
thenecho 'nginx is starting'exit 1
fi
}
function stop(){
    /application/nginx/sbin/nginx -s stop &>/dev/nullsleep 1
if [ `netstat -lntup|grep nginx|wc -l` -eq 0 ]
thenecho 'nginx is down'exit 1
fi
}
function reload(){
    /application/nginx/sbin/nginx -s reload &>/dev/null
if [ `netstat -lntup|grep nginx|wc -l` -ne 0 ]
thenecho 'nginx is reload'exit
elseecho 'nginx is dead!'
fi
}
main(){
    
if [ $# -eq 0 ]
thenusage
fi
if [ "$1" = "start" ]
thenstartelif [ "$1" = "stop" ]thenstopelif [ "$1" = "reload" ]thenreloadelif [ "$1" = "restart" ]thenstopsleep 1start
elseusage
fi
}
main $*编写好脚本之后开始配置chkconfig
首先确定自启动脚本文件在不在目录/etc/init.d/下面,不在的添加进来
然后
#赋予脚本的执行权限
chmod +x /etc/init.d/nginx  #添加到自启动服务当中 
chkconfig --add nginx   #查看服务是否已经添加
chkconfig --list nginx#启动服务
chkconfig nginx on#关闭服务
chkconfig nginx off

CentOS 7 systemctl 自启动管理
systemctl知识简介
从CentOS7 Linux开始,系统里的网络服务启动已经从传统的service改成了systemctl(一个systemd工具,主要负责控制systemd系统和服务管理器。),管理开机自启动的命令也从chkconfig改为了systemctl,由systemctl一个命令代替了CentOS7以前系统中的service和chkconfig两个命令。系统服务的脚本也从传统的路径的/etc/init.d(/etc/rc.d/init.d/),改了/usr/lib/systemd(除此之外还有/etc/systemd/system),需要自启动运行的程序,一般存在这个系统服务目录下,即:/usr/lib/systemd/system目录,每一个服务以“服务名.service”结尾,该文件的内容一般分为3部分:即[Unit]、[Service]和[Install]

CentOS7:
#systemctl管理的nginx服务配置说明
#确定配置服务的目录必须要在/usr/lib/systemd/system/nginx.service目录之下
[root@any ~]#cat /usr/lib/systemd/system/nginx.service 
[Unit]
Description=Nginx service
After=network.target[Service]
Type=forking  #<==后台运行。
PIDFile=/var/run/nginx.pid                #<==PID路径。
ExecStart=/etc/rc.d/init.d/nginx start    #<==启动服务脚本,介绍在下文。
ExecReload=/etc/rc.d/init.d/nginx restart #<==重启服务脚本,介绍在下文。
ExecStop=/etc/rc.d/init.d/nginx stop      #<==兼容停止服务脚本,介绍在下文。
PrivateTmp=true    #<==开启独立的空间。[Install]
WantedBy=multi-user.target  #<==这里为设置多用户级别。============================================================
nginx自启动脚本:
#!/bin/bash
#Author:any
#Blog:http://xxx.com
#Time:2020-10-22 10:57:08
#Name:nginx.sh
#Version:VI.
. /etc/init.d/functions   #初始化库函数
pid='/application/nginx/logs/nginx.pid'
path='/application/nginx/sbin'
function usage(){
    echo "Usage:$0 {start|restart|stop|reload}"exit 0
}
function start(){
    
if [ ! -f $pid ]
then$path/nginxsleep 1action 'nginx is starting' /bin/true     #调用库函数当中的action 提示函数retval=$?
elseecho 'nginx is on!!!'exit 1
fireturn $retval
}
function stop(){
    
if [ -f $pid ]
then$path/nginx -s stopsleep 1action 'nginx is off' /bin/trueretval=$?
elseecho 'nginx is off!!!'exit 1
fireturn $retval
}
function reload(){
    
if [ -f $pid ]
then$path/nginx -s stop$path/nginxsleep 1action 'nginx is reload' /bin/trueretval=$?
elseecho 'nginx is dead!!!'
fireturn $retval
}
main(){
    
if [ $# -ne 1 ]
thenusage
fi
case $1 instart)startretval=$?;;    stop)stopretval=$?;;reload)reloadretval=$?;;*)usage;;
esac
}
main $*

11、抓阄脚本

每一个人随机对应1-99中的一个数,定向到一个文件当中,然后从文件当中选出三个人以及对应的数字。
抓阄分析:
1、输入一个人的名字,判断这个名字在name_file文件当中是否存在,如存在则表示该同学已经抽过,否则随机生成一个数(1-99),放nemae_file文件当中保留。
2、判断随机数是否重复,如果重复则要重新生成随机数使用while循环实现一直输入名字。

root@any /server/scripts]#cat zhajiu.sh 
#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-29 14:43:12
#Name:zhajiu.sh
#Version:VI.0
#Discription:To 
#######################################################
name_file=/opt/zhuajiu.log
[ -f $name_file ] || touch $name_file
usage(){
    echo "输入错误,请正确输入!!"
}
check_name(){
    while truedoread -p "请输入你的名字:" nameif [ ${#name} -eq 0 ]thenusageelseif [ `grep -w $name $name_file|wc -l` -eq 0 ]then num=`expr $RANDOM % 99 + 1`if [ `grep $num $name_file|wc -l` -eq 0 ]thenecho "$name,your number is $num!"|tee -a $name_file fielseecho "your name is already exit!"echo "`grep $name $name_file`"fifidone
}
check_name

12、破解RANDON随机数

有一窜数字是md5sum加密之后在截取的内容是:
21029299
00205d1c
a3da1677
1f6d12dd
890684b
问原来的数值时多少?
分析:
RANDOM随机数的范围是0-32767,把这所有的数md5sum处理之后的都列出来,再比对就好了

#!bin/bash
#######################################################
#Author:any
#Blog:http://xxx.com
#Time:2020-10-26 09:23:07
#Name:pojie.sh
#Version:VI.0
#Discription:To 
#######################################################
arr=(2102929900205d1ca3da16771f6d12dd890684b)
>/tmp/md5.txt
getmd5sum(){
    for n in {
    1..32767}do{
    stat="echo $n|md5sum|cut -c 1-8"echo "$stat $n" >>/tmp/md5sum.txt}&        #括号内命令并行(一同)执行done
}
findmd5(){
    #取出元素数组并且用“|”分隔开#word="${arr[*]}|tr ' ' '\n'"word="${arr[*]}|sed -r 's# #|#g'"     #取出数组元素并且用"|"分隔开egrep "$word" /tmp/md5sum.txt     #同时过滤出不同字符串的内容
}
if [ ! -s /tmp/md5sum.txt  ]
thengetmd5sum
elsefindmd5dum
fi

13、批量查看多个网址是否是正常

1、把网站定义成一个数组
2、wget或者curl判断网站是否正常,不正常则报警[root@any /server/scripts]#vim a.sh
#Blog:http://xxx.com
#Time:2020-10-29 15:56:46
#Name:a.sh
#Version:VI.0
#Discription:To 
#######################################################
. /etc/init.d/functions #引用库函数
arr=(
www.baidu.com
blog.etiantian.com
www.jd.com
10.0.0.61
)
usage(){
    echo "usage:$0 url"exit 0
}url(){
    for ((i=0;i<${#arr[*]};i++))dowget -T 2 --tries 2 -q ${arr[i]} &>/dev/nullif [ $? -eq 0 ]thenaction "${arr[i]} is ok." /bin/trueelseaction "${arr[i]} is error." /bin/falsefidoneexit 0
}
url

14、字符串去重排序

给一段字符串或者文本进行数量排序:

[root@any ~]#vim 2.txt 
I am any,I think there where is a way,there is a will方法1:tr替换与awk删选
#tr ‘ ,.’ ‘\n’ <2.txt|awk ‘{S[$1]++}END{for(key in S) print S[key],key}’|sort -rn
tr ‘ ,.’ ‘\n’ <2.txt|awk{
    S[$1]++}END{
    for(key in S) print S[key],key|"sort -rn"}’ 2.txt方法2:tr替换与sort、uniq 排序
tr ‘ ,.’ ‘\n’ <2.txt|sort|uniq -c|sort -rn方法3:awk删选
#awk -F '[ ,.]+' ‘{for(i=1;i<=NF;i++)S[$i]++}END{for(key in S) print S[key],key|"sort -rn"}' 2.txt
awk -F '[ ,.]+' '{for(i=1;i<=NF;i++)S[$i]++}END{for(key in S) print S[key],key}' 2.txt =======================================================================================================================
分成单个字母排序
方法1:
awk -F "" '{for(i=1;i<=NF ;i++)S[$i]++}END{for(key in S) print S[key],key}' 2.txt|sort -rn方法2:
grep -o :--仅匹配只打印匹配行的匹配(非空)部分,每个匹配部分都在单独的输出行上
grep -o '[^ ,.]' 2.txt|sort|uniq -c|sort -rn

15 、web以及mysql服务异常监测

端口检测:
netstat -lntup|grep
pe -ef|grep 
lsof -i :web获取:
wget -o --timeout 2 --tries 2 --spider  (网站)-o:所有的消息记录到日志文件--timeout:超时时间--tries:尝试次数--spider:模拟爬取文件curl -o /dev/null (ip)-o /dev/null :输出定向到空检测数据库:
#if [ `nestat -lntup|grep mysqld|wc -l` -gt 0 ]
#if [ `lsof -i :80|wc -l` -gt 0 ]
if [ `ps -ef|grep mysql|wc -l` -gt 0 ]
thenecho “mysql is alived!elseecho “mysql is dead”systemctl start mysql       #此命令是必须要配置好mysql的启动脚本之后才能执行
fi检测web网站:[root@any /server/scripts]#cat check_url.sh 
#!/bin/bash
#Author:any
#Blog:http://xxx.com
#Time:2020-10-22 14:31:54
#Name:url.sh
#Version:VI.0
. /etc/init.d/functions #引用库函数
usage(){
    echo "usage:$0 url"exit 0
}
url(){
    wget -q $1 &>/dev/null
if [ $? -eq 0 ]
thenaction "$1 is ok." /bin/trueexit 0
elseaction "$1 is error." /bin/trueexit 0
fi
}
main(){
    
if [ $# -eq 0 ]
thenusage
elseurl $1
fi
}
main $*