试题一

写一个监控网卡的脚本,需要满足以下要求:

  1. 每10分钟检测一次指定网卡的流量。
#!/bin/bash
# yum install sysstat -y
[ -f /etc/profile ] && . /etc/profile

function network_check() {
    interval=$1
    flag_count=$2
    network_eth=$3
    d_time=`date +'%Y-%m-%d %H:%M:%S'`
    rx=`sar -n DEV $interval $flag_count|grep $network_eth|egrep -v "^[0-9]"|awk '{print $5}'`
    tx=`sar -n DEV $interval $flag_count|grep $network_eth|egrep -v "^[0-9]"|awk '{print $6}'`
    rx_kbps=`echo "$rx * 8"|bc`
    tx_kbps=`echo "$tx * 8"|bc`
    echo "$d_time $network_eth input:${rx_kbps}kbps output:${tx_kbps}kbps"

}

while true
do
    network_check 1 5 ens192
    sleep 5
done

试题二

写一个shell脚本,通过curl -I 返回的状态码来判定所访问的网站是否正常。 比如,当状态码为200时,才算正常。

#!/bin/bash

function web_check() {
    web_url=$1
    web_code=`curl --connect-timeout 3 -I -s $web_url|sed -n '1p'`
    if [ -z "$web_code" ]; then
        echo "网站访问失败,请确认域名是否正确"
        return 5
    fi
    status_code=`echo $web_code|awk '{print $2}'`
    if [ $status_code -eq 200 ]; then
        echo "url:$web_url status:$status_code 请求成功"
    else
        echo "url:$web_url status:$status_code 请求失败"
    fi
}

web_check www.qq.com

试题三

将用户家目录(考虑到执行脚本的用户可能是普通用户也可能是root)下面小于5KB的文件打包成tar.gz的压缩包,并以当前日期为文件名前缀,例如,2018-03-15.tar.gz。

#!/bin/bash

base_dir=`pwd`
user=`whoami`
d_time=`date +'%Y-%m-%d'`
if [ "$user" == "root" ]; then
    cd /root; find ./ -type f -size -5k |xargs tar -czvf /tmp/$d_time.tar.gz
else
    cd /home/$user ; find ./ -type f -size -5k |xargs tar -czvf /tmp/$d_time.tar.gz
fi

cd $base_dir

试题四

一个同学不小心用iptables规则把sshd端口22给封掉了,结果不能远程登陆,要想解决这问题,还要去机房,登录真机去删除这规则。 问题来了,要写个监控脚本,监控iptables规则是否封掉了22端口,如果封掉了,给打开。 写好脚本,放到任务计划里,每分钟执行一次。

#/bin/bash

function firewalld_check() {
    firewall-cmd --list-all|grep 'services'|grep ssh &>/dev/null
    if [ $? -eq 0 ]; then
        echo "ssh端口正常"
    else
        echo "防火墙禁用ssh,开启中..."
        firewall-cmd --permanent --zone=public --add-service=ssh
        firewall-cmd --reload
    fi
}

while true
do
    firewalld_check
    sleep 10
done
#备注:未验证

试题五

已知nginx访问的日志文件在/usr/local/nginx/logs/access.log内,请统计下早上10点到12点 来访ip最多的是哪个?

#!/bin/bash
access_log=/data/logs/nginx/access_oms.log

y=`date +'%Y'`
ip_max=`sed -n "/\/$y:10/,/\/$y:12/"p $access_log |awk '{print $9}'|sort -r |uniq -c|head -1|awk '{print $2}'`
echo $ip_max

试题六

写一个shell脚本。提示输入一个暂停的数字,然后从1打印到该数字。然后询问是否继续。继续的话再输入一个数字接着打印,否则退出脚本。

例:如果输入的是5,打印1 2 3 4 5,然后继续输入15,然后打印6 7 …14 15 以此类推。

#!/bin/bash

flag=true
read -p '输入一个数字:' first_choose
for i in `seq 1 $first_choose`
do
    echo $i
done

while $flag
do
    read -p '是否继续[y|n]:' choose
    if [  "$choose" == "N" -o "$choose" == "n" ]; then
        break 
    fi
    read -p '输入一个数字:' next_choose
    for i in `seq $first_choose $next_choose`
    do
        echo $i
    done
done

试题七

在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:

# cat a.sh |sed '5a# This is a test file.\n# Test insert line into this file.' 

试题八

设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式”yymmdd_etc.tar.gz”,yy为年,mm为月,dd为日。

#!/bin/bash

d=`date +%d`
d_time=`date +%Y%m%d`
base_dir=`pwd`
[ ! -d /root/bak ] && mkdir -p /root/bak
if [ $d -eq 01 ]; then
    cd / ; tar -czf /root/bak/${d_time}_etc.tar.gz etc
    cd $base_dir
fi

#备注:未经测试

试题九

需求是,把所有的成员平均分成若干个小组。这里,提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结果应该不一致。

#!/bin/bash
#这个脚本用来给人员分组
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02

#人员列表文件
f=member.txt
#小组数
group_n=7
#人员总数
member_n=`wc -l $f|awk '{print $1}'`

#根据姓名计算该用户所在小组的id
get_n()
{
    #根据姓名计算cksum值
    l=`echo $1|cksum|awk '{print $1}'`
    #获取一个随机数
    n1=$RANDOM
    #cksum值和随机数相加,然后除以小组数取余,这样可以确保每次获取到的余数都不一样
    n2=$[$n1+$l]
    g_id=$[$n2%$group_n]
    #假如小组数为7,则余数范围0-6,如果余数为0,则小组为7
    if [ $g_id -eq 0 ]
    then
        g_id=$group_n
    fi
    echo $g_id
}

for i in `seq 1 $group_n`
do
    #n_$i.txt为临时文件,用来记录该小组内的成员
    #脚本之前执行过,则该文件会存在,本次执行脚本前应该删除掉这个临时文件
    [ -f n_$i.txt ] && rm -f n_$i.txt
done

shuf $f|while read name
do
    #计算用户所在小组的id
    g=`get_n $name`
    #将人员追加写入到他对应的小组里
    echo $name >> n_$g.txt
done

#定义计算文件行数的函数
nu(){
    wc -l $1|awk '{print $1}'
}

#获取组员人数最多的小组
max(){
    ma=0
    for i in `seq 1 $group_n|shuf`
    do
        n=`nu n_$i.txt`
        if [ $n -gt $ma ]
        then
            ma=$n
       fi
    done
    echo $ma
}

#获取组员人数最少的小组
min(){
    mi=$member_n
    for i in `seq 1 $group_n|shuf`
    do
       n=`nu n_$i.txt`
       if [ $n -lt $mi ]
       then
           mi=$n
       fi
    done
    echo $mi
}

#定义四舍五入函数
div()
{
    n=`echo "scale=1;$1/$2"|bc`
    n1=`echo "scale=1;$n+0.5"|bc`
    echo $n1|cut -d. -f1
}

#小组组员平均值(非四舍五入)
ava_n=$[$member_n/$group_n]
#小组组员平均值(四舍五入)
ava_n1=`div $member_n $group_n`

if [ $ava_n -eq $ava_n1 ]
then
    #定义初始最小值
    ini_min=1
    #以下while循环要做的事情,就是要把人数多的组里的人搞到人数少的组里去
    #此while循环的条件是,当人数最少的组成员数小于组员平均值
    while [ $ini_min -lt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
            #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一个人名
        name=`tail -n1 $f1`
        #将这个人名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_min=`min`
    done
else
    #定义初始最大值
    ini_max=$member_n
    while [ $ini_max -gt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
                #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一个人名
        name=`tail -n1 $f1`
        #将这个人名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_max=`max`
    done
fi

for i in `seq 1 $group_n`
do
    echo -e "\033[34m$i 组成员有:\033[0m"
    cat n_$i.txt
    #把临时文件删除
    rm -f n_$i.txt
    echo
done

#备注:不会

试题十

写一个shell脚本,比较两个数的大小,支持浮点数,两个数通过shell参数的形式提供。

#!/bin/bash

check_1=`echo $1|sed 's/[0-9.]//g'`
check_2=`echo $2|sed 's/[0-9.]//g'`

if [ -n "$check_1" -o -n "$check_2" ]; then
    echo "请输入整数"
    exit 5    
fi

s=`echo "$1-$2"|bc`
if [ "$s" == "0" ]; then
   echo "\$1=\$2"
elif [ `echo "$s"|grep "-"` ]; then
   echo "\$1<\$2"
else
   echo "\$1>\$2"
fi

方法二

#!/bin/bash

check_1=`echo $1|sed 's/[0-9.]//g'`
check_2=`echo $2|sed 's/[0-9.]//g'`

if [ -n "$check_1" -o -n "$check_2" ]; then
    echo "请输入整数"
    exit 5    
fi

n=`echo "$1>$2"|bc`
if [ $n -eq 1 ]; then
    echo "\$1>\$2"
else
    if [ "$1" == "$2" ]; then
        echo "\$1=\$2"
    else 
        echo "\$1<\$2"
    fi

fi
最后修改日期: 2020年8月26日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。