试题十一
写一个脚本实现如下功能: 输入一个数字,然后运行对应的一个命令。
显示命令如下:
*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
试题十三
在服务器上,写一个监控脚本,要求如下:
- 每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
- 若没有正常启动还需再一次启动,最大不成功数超过5次则需要立即发邮件通知管理员,并且以后不需要再检测!
- 如果启动成功后,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给解封。 假设:
- 一分钟内请求量高于100次的IP视为不正常请求。
- 访问日志路径为/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/目录下的二级、三级、… 等子目录里面的文件。
留言