试题十一

写一个脚本实现如下功能: 输入一个数字,然后运行对应的一个命令。

显示命令如下:

*cmd meau** 1 – date 2 – ls 3 – who 4 – pwd 当输入1时,会运行date, 输入2时运行ls, 以此类推。

核心要点:

  • case判断
#!/bin/bash
red='\e[91m'
green='\e[92m'
yellow='\e[93m'
magenta='\e[95m'
cyan='\e[96m'
none='\e[0m'

function meau() {
    shell_cwd=$1
    $shell_cwd
}
while true
do
    echo -e "$yellow  1. $none执行date命令"
    echo
    echo -e "$yellow  2. $none执行ls命令"
    echo
    echo -e "$yellow  3. $none执行who命令"
    echo
    echo -e "$yellow  4. $none执行pwd命令"
    echo 
    echo -e "$yellow  q. $none执行exit命令"
    echo 
    read -p "$(echo -e "请选择菜单 [${magenta}1-4$none]:")" choose
    if [ -z $choose ]; then
        exit 1
    else
        case $choose in
          1)
            meau date
            ;;
          2)
            meau ls
            ;;
          3)
            meau who
            ;;
          4)
            meau pwd
            ;;
          q|Q)
            exit 4
            ;;
          *)
            echo "USAGE:{1|2|3|4|q}"
            ;;
        esac
    fi
done

试题十二

用shell脚本实现如下需求:

添加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。 提示:

1.随机密码使用命令mkpasswd

2.在脚本中给用户设置密码,可以使用echo然后管道passwd命令

核心要点:

  • seq实现数字递增
  • RANDOM创建随机密码
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
PASSWORD_LOG=/tmp/pass.txt
[ ! -f $PASSWORD_LOG ] && touch $PASSWORD_LOG

function user_add() {
    user_wc=$1
    n=`echo "$user_wc"|wc -L`
    if [ "$user_wc" == "0" -a "$n" == "1" ]; then
        user_wc=00
    elif [ "$user_wc" != "0" -a "$n" == "1" ]; then
        user_wc=0${user_wc}
    fi
    for i in `seq -w 00 $user_wc`
    do
        id user_$i &>/dev/null
        if [ $? -eq 0 ]; then
            echo "user_$i已存在"
        else
            pass=`echo $RANDOM|md5sum |cut -c 1-10`
            useradd user_$i
            echo "$pass"|passwd --stdin user_$i
            if [ $? -eq 0 ]; then
                echo "用户名:user_$i">> $PASSWORD_LOG
                echo "密码:$pass" >> $PASSWORD_LOG
                echo "">> $PASSWORD_LOG
            fi
        fi
    done
}

user_add 11

试题十三

在服务器上,写一个监控脚本,要求如下:

  1. 每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
  2. 若没有正常启动还需再一次启动,最大不成功数超过5次则需要立即发邮件通知管理员,并且以后不需要再检测!
  3. 如果启动成功后,1分钟后再次检测httpd进程数,若正常则重复之前操作(每隔10s检测一次),若还是大于等于500,那放弃重启并需要发邮件给管理员,然后自动退出该脚本。假设其中发邮件脚本为之前使用的mail.py

核心要点:

  • 检测进程命令ps -C httpd –no-heading
sum_chek=`ps -C httpd --no-heading|wc -l`;if [ $sum_chek -gt 100 ]; then echo 'gt 100'; else echo 'lt 100'; fi
#备注:这种进程进程数脚本没必要写

试题十四

需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!并且每隔半小时把不再发起请求或者请求量很小的ip给解封。 假设:

  1. 一分钟内请求量高于100次的IP视为不正常请求。
  2. 访问日志路径为/data/logs/access_log。

用第2例中的1.log作为演示日志

112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com “/seccode.php?update=0.5593110133088248″ 200 ″http://formula-x.haotui.com/registerbbs.php” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)”
61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com “/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301 ″http://xyzdiy.5d6d.com/thread-1435-1-23.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”

核心要点:

  • awk、cut等命令使用
  • firewalld理解
#!/bin/bash
[ -f /etc/profile  ] && . /etc/profile

FIREWALLD_LOG=/tmp/firewall.log
FIREWALLD_BAD_LOG=/tmp/firewall_bad.log
FIREWALLD_ERROR_LOG=/tmp/firewall_error.log
CHECK_LOG=1.log
last_min=`date -d '-1 min' +%Y:%H:%M`
HTTP_PORT=80

[ ! -f $FIREWALLD_LOG ] && touch $FIREWALLD_LOG
[ ! -f $FIREWALLD_BAD_LOG ] && touch $FIREWALLD_BAD_LOG
[ ! -f $FIREWALLD_ERROR_LOG ] && touch $FIREWALLD_ERROR_LOG

function firewall_reject() {
    server_port=$1
    host_ip=$2
    d_time=`date +'%Y-%m-%d %H:%M:%S'`
    firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="$host_ip" port protocol="tcp" port="$server_port" reject" &>/dev/null
    if [ $? -eq 0 ]; then
        echo "$d_time REGECT server:$host_ip server_port:$server_port success" >> $FIREWALLD_LOG
        echo "$d_time $host_ip $server_port" >> $FIREWALLD_BAD_LOG
    else
        echo "$d_time REGECT server:$host_ip server_port:$server_port faild" >> $FIREWALLD_LOG
    fi
    firewall-cmd --reload
}

function firewall_allow() {
    server_port=`echo $@|awk '{print $4}'`
    host_ip=`echo $@|awk '{print $3}'`
    old_time=`echo $@|cut -d " " -f 1,2`
    d_time=`date +'%Y-%m-%d %H:%M:%S'`
    d_time_stamp=`date -d "$d_time" +%s`
    old_time_stamp=`date -d "$old_time" +%s`
    statistics_time=$[$d_time_stamp-$old_time_stamp]
    server_port=`grep "$host_ip" $FIREWALLD_BAD_LOG|awk '{print $4}'`
    if [ $statistics_time -gt 3600  ]; then
        firewall-cmd --permanent --zone=public --remove-rich-rule='rule port port="$server_port" protocol="tcp" family="ipv4" source address="$host_ip" reject' &>/dev/null
        if [ $? -eq 0 ]; then
            echo "$d_time ALLOW reject server:$host_ip server_port:$server_port success" >> $FIREWALLD_LOG
        else
            echo "$d_time ALLOW reject server:$host_ip server_port:$server_port faild" >> $FIREWALLD_LOG
        fi
    fi
    firewall-cmd --reload
}

egrep "$last_min:[0-9]+" $CHECK_LOG |awk '{print $1}'|sort |uniq -c|awk '$1>100{print $2}'|while read line
do  
    grep $line $FIREWALLD_BAD_LOG &>/dev/null
    if [ $? -ne 0 ]; then
        firewall_reject $HTTP_PORT $line
    fi
done

#默认一小时解封
cat $FIREWALLD_BAD_LOG |while read i
do
    echo ">>>$i"
    firewall_allow $i
done

备注:firewall检测状态存在难度,这里默认改成1小时候进行解封,没细策,可能存在bug。另外关于access日志每天需要做切割

试题十五

请仔细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字。

10 31 53 77 105 141 …….

核心要点:

  • 计算两个数值之间的差值
#!/bin/bash
x=10
y=21
for i in `seq 0 15`
do 
    echo $x
    x=$[$x+$y]
    z=$[2**$i]
    y=$[$y+$z]
done

试题十六

写个shell,看看你的Linux系统中是否有自定义用户(普通用户),若是有,一共有几个?

核心要点

  • grep、cut、awk使用
cat /etc/passwd|while read line; do user=`echo $line|awk -F ':' '$3>1000{print $1}'`; if [ -n "$user" ]; then echo $user;sum_count=$[$sum_count+1]; echo $sum_count ;fi; done

试题十七

写一个shell脚本,检测所有磁盘分区使用率和inode使用率并记录到以当天日期为命名的日志文件里,当发现某个分区容量或者inode使用量大于85%时,发邮件通知你自己。

核心要点:

  • df使用
  • awk使用
df -i |egrep "/dev/sd[a-z][0-9]+"|awk -F "%" '{print $1}'|awk '$NF>85{print $1}'|while read line; do d_time=`date +'%Y-%m-%d %H:%M:%S'`; echo "$d_time $line warning"; done

试题十八

有一台服务器作为web应用,有一个目录(/data/web/attachment)不定时地会被用户上传新的文件,但是不知道什么时候会上传。所以,需要我们每5分钟做一次检测是否有新文件生成。

请写一个shell脚本去完成检测。检测完成后若是有新文件,还需要将新文件的列表输出到一个按年、月、日、时、分为名字的日志里。

核心要点:

  • find使用
#!/bin/bash
basedir=/data/web/attachment
d_time=`date -d '5 min ago' +'%Y%m%d%H%M'`

[ ! -d $basedir ] && exit 6
find $basedir -type f -mmin -5 > /tmp/file.list
nnc=`wc -l /tmp/file.list|awk '{print $1}'`
if [ $nnc -gt 0 ]; then
    mv /tmp/file.list /tmp/$d_time.list
fi

试题十九

写一个shell脚本来看看你使用最多的命令是哪些,列出你最常用的命令top10。

核心要点:

  • awk等命令使用
history |awk '{print $2}'|sort |uniq -c|sort -n -k 1 -r|head -10

试题二十

假如需要每小时都去执行一个脚本。在脚本中实现这样的功能,当时间是0点和12点时,需要将目录/data/log/下的文件全部清空,

注意只能清空文件内容而不能删除文件。而其他时间只需要统计一下每个文件的大小,一个文件一行,输出到一个按日期和时间为名字的日志里。

需要考虑/data/log/目录下的二级、三级、… 等子目录里面的文件。

最后修改日期: 2020年8月21日

作者

留言

撰写回覆或留言

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