1.企业级生产高级实战案例
范例10_10:写一个Shell脚本解决类DDOS攻击的生产案例。请根据web日志或者或者系统网络连接数,监控当某个IP并发连接数,若短时内PV达到100,即调用防火墙命令封掉对应的IP。防火墙命令为:
iptables -I INPUT -s IP地址 -j DROP。
答案:
while true
do
# awk -F "[ :]+" '/ESTABLISHED/{print $(NF-3)}' netstat.log|sort|uniq -c|sort -rn|head -10 >/tmp/ip.log
# awk -F "[ :]+" '{print $1}' access_2010-12-8.log|sort|uniq -c|sort -rn>/tmp/ip.log
awk '{++S[$1]} END {for(key in S) print S[key],key}' access_2010-12-8.log|sort -rn >/tmp/ip.log
while read line
do
ip=`echo $line|awk '{print $2}'`
i=`echo $line|awk '{print $2}'|awk -F "[ .]+" '{print $NF}'`
count=`echo $line|awk '{print $1}'`
#if [ $count -gt 100 ] && [ `iptables -nL|grep "$ip"|wc -l` -lt 1 ]
if [ $i -gt 100 ] && [ `iptables -nL|grep "$ip"|wc -l` -lt 1 ]
then
echo "$ip is 危险的"
iptables -I INPUT -s $ip -j DROP
else
echo "$ip is 安全的"
fi
done</tmp/ip.log
sleep 5
done
2.实现通过传参的方式往/etc/openvpn_authfile.conf里添加用户,具体要求如下。
1)命令用法为:
USAGE: sh adduser {-add|-del|-search} username
2)传参要求为:
如果参数为-add时,表示添加后面接的用户名。
如果参数为-del时,表示删除后面接的用户名。
如果参数为-search时,表示查找后面接的用户名。
3)如果有同名的用户则不能添加,没有对应用户则无需删除,查找到用户以及没有用户时给出明确提示。
4)/etc/openvpn_authfile.conf不能被所有外部用户直接删除及修改
答案:
. /etc/init.d/functions
filename=/etc/openvpn_authfile.conf
[ ! -f $filename ] && touch $filename
usage(){
cat <<EOF
USAGE: `basename $0` {-add|-del|-search} username
EOF
}
if [ $UID -ne 0 ] ;then
echo "Your are not supper user,please call root!"
exit 1;
fi
if [ $# -ne 2 ] ;then
usage
exit 2;
fi
case "$1" in
-a|add)
shift
if grep "$1" ${filename} >/dev/null 2>&1
then
action $"vpnuser,$1 is exist" /bin/false
exit
else
chattr -i ${filename}
/bin/cp ${filename} ${filename}.$(date +%F%t)
echo "$1" >> ${filename}
[ $? -eq 0 ] && action $"Add $1" /bin/true
chattr -i ${filename}
fi
;;
-d|del)
shift
if [ `grep -w "$1" ${filename}|wc -l` -lt 1 ]
then
action $"vpnuser,$1 is not exist" /bin/false
exit
else
chattr -i ${filename}
/bin/cp ${filename} ${filename}.$(date +%F%T)
sed -i "/^${1}$/d" ${filename}
[ $? -eq 0 ] && action $"Del $1" /bin/true
chattr +i ${filename}
exit
fi
;;
-s|-search)
shift
if [ `grep -w "$1" ${filename}|wc -l` -lt 1 ]
then
echo $"vpnuser,$1 is not exist";exit
else
echo $"vpnuser,$1 is exist";exit
fi
;;
*)
usage
exit
;;
esac
3.已知Nginx Web服务的管理命令如下——
启动服务命令为/application/nginx/sbin/nginx
停止服务命令为/application/nginx/sbin/nginx -s stop
请用case语句开发脚本实现Nginx服务启动及关闭功能,具体脚本命令为/etc/init.d/nginx {start|stop|restart},并实现可通过chkconfig进行开机自启动管理(CentOS6),
同时实现通过systemctl进行开机自启动管理(CentOS7)。
答案:
#chkconfig: 2345 40 98
path=/application/nginx/sbin
pid=/application/nginx/logs/nginx.pid
retval=0
. /etc/init.d/functions
start(){
if [ -f $pid ];then
#if [ `netstat -lntup|grep nginx|wc -l` -eq 0 ];then
$path/nginx
retval=$?
if [ $retval -eq 0 ];then
action " nginx is startted" /bin/true
return $retval
else
action " nginx is startted" /bin/false
return $retval
fi
return 0
fi
}
stop(){
if [ -f $pid ];then
retval=$?
action " nginx is stopped" /bin/true
return $retval
else
action " nginx is stopped" /bin/false
return $retval
fi
else
echo "nginx is not running"
return $retval
fi
}
case "$1" in
start)
start
retval=$?
;;
stop)
stop
retval=$?
;;
restart)
stop
sleep 1
start
retval=$?
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit $retval
4.Linux系统计算从1加到100之和
http://oldboy.blog.51cto.com/2561410/767862
答案:
sum=0
a=1
while [ $a -le 100 ]
do
let sum=sum+a
((a++))
done
echo $sum
5.猜数字游戏。首先让系统随机生成一个数字,给这个数字定一个范围(1-60),让用户输入猜的数字,对输入进行判断,如果不符合要求,就给予高或低的提示,
猜对后则给出猜对用的次数,请用while语句实现。
超越了全国多少用户。
答案:
total=0
export LANG="zh_CN.UTF-8"
NUM=$((RANDOM%60))
echo "当前苹果的价格是一斤$NUM元"
usleep 100000
clear
echo '这苹果多少钱一斤啊?猜猜0-60的数字'
apple(){
read -p "请输入你的价格:" price
expr $price +1 &>/dev/null
if [ $? -ne 0 ]
then
echo "请输入数字"
apple
fi
}
guess(){
((total++))
if [ $price -eq $SUM ]
then
echo "猜对了,就是$NUM元"
if [ $total -le 3 ];then
echo "一共猜了$total次,太牛了。"
elif [ $total -gt 3 -a $total -le 6 ];then
echo "一共猜了$total次,次数有点多,加油啊!"
elif [ $total -gt 6 ];then
echo "一共猜了$total次,行不行,猜了这么多次"
fi
exit 0
elif [ $price -gt $SUM ];then
echo "嘿嘿,要不你用这个价买?"
echo "才给你一次机会,请继续猜:"
apple
elif [ $price -lt $SUM ];then
echo "嘿嘿,要不你用这个价买?"
echo "才给你一次机会,请继续猜:"
apple
fi
}
main(){
apple
while true
do
guess
done
}
main
6.手机充值10元,每发一次短信(输出当前余额)花费1角5分钱,当余额低于1角5分钱时不能发短信,提示“余额不足,请充值”(允许用户充值后继续发短信),请用while语句实现。
答案:
export LANG="zh_CN.UTF-8"
sum=15
msg_fee=15
msg_count=0
menu(){
cat <<END
当前余额为${sum}分,每条短信需要${msg_fee}分
============================================
1.充值
2.发信息
3.退出
============================================
END
}
recharge(){
read -p "请输入金额充值:" money
expr $money + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "then money your input is error,must be int."
else
sum=$(($sum+$money))
echo "当前余额为:$sum"
fi
}
sendInfo(){
if [ ${sum} -lt $msg_fee ]
then
printf "余额不足:$sum,请充值。\n"
else
while true
do
read -p "请输入短信内容(不能有空格):"msg
sum=$(($sum-$msg_fee))
printf "Send "$msg" successfully!\n"
printf "当前余额为:$sum\n"
if [ $sum -lt $msg_fee ]
then
printf "余额不足,剩余$sum分\n"
return 1
fi
done
fi
}
main(){
while true
do
menu
read -p "请输入数字选择:" men
case "$men" in
1)
recharge
;;
2)
sendInfo
;;
3)
exit 1
;;
*)
printf "选择错误,必须是{1|2|3}\n"
esac
done
}
main
sum=1000
i=15
while ((sum>=i))
do
((sum=sum-i))
[ $sum -lt $i ] && break
echo "send message,left $sum"
done
echo "money is not enough:$sum"
##############################################################
sum=1000
i=15
while ((sum>=i))
do
((sum=sum-i))
[ $sum -lt $i ] &&{
echo "send message,left $sum money is notenough"
break
}
echo "send message,left $sum"
done
7.使用while守护进程方式监控网站,每隔10秒确定网站是否正常。
答案:
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
usage(){
if [[ ! $1 =~ http://www.*com ]]
then
echo "Usage:$0 http://www.xx.com"
exit 1
fi
}
check_url(){
wget -q $1 &>/dev/null
retval=$?
if [ $retval -eq 0 ]
then
action "url is ok." /bin/true
else
action "url is no." /bin/false
fi
}
main(){
while true
do
usage $1
check_url $1
sleep 5
done
}
main $*
8.方式1:采用exec读取文件后,然后进入while循环处理。
exec<FILE
sum=0
while read line
do
cmd
done
方式2:使用cat读取文件内容,然后通过管道进入while循环处理。
cat FILE_PATH|while read line
do
cmd
done
方式3:在while循环结尾done通过输入重定向指定读取的文件。
while read line
do
cmd
done<FILE
9.企业Shell面试题1:批量生成随机字符文件名案例
使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含oldboy固定字符串加10个随机小写字母,名称示例如下:
[root@oldboy scripts]# ls /oldboy
oldboy_amaeeurmja.html oldboy_jmtiqwhinw.html oldboy_rnbwmjkjkh.html oldboy_yhufdiceox.html
oldboy_antodvkjcf.html oldboy_ncivkckvok.html oldboy_tyqfhfxvup.html
oldboy_epwmszmttm.html oldboy_osjmrurgsx.html oldboy_vpgslhajdn.html
答案:
[ d /oldboy ] && rm -rf /oldboy
[ d /oldboy ] || mkdir /oldboy
cd /oldboy
for n in `seq 10`
do
name=`openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11`
touch ${name}_oldboy.html
done
10.企业Shell面试题2:批量改名特殊案例
将上面试题19.1.1中结果文件名中的oldboy字符串全部改成oldgirl(最好用for循环实现),并且将扩展名html全部改成大写HTML。
三种方法实现:
答案:
方法1:
Path=/oldboy
[ -d $Path ] || mkdir $Path
cd $Path
for file1 in `ls`
do
mv $file1 ${file1/oldboy.html/oldgirl.HTML}
done
方法2:
rename专业改名
[root@web01 /oldboy]# rename "oldgirl.HTML" "oldboy.html" *HTML
[root@web01 /oldboy]# ls
fzewmfbowb_oldboy.html kfixfkghqz_oldboy.html qaxuezrdyh_oldboy.html vkftijhssz_oldboy.html
ibcmutcmyj_oldboy.html ovqxxevhlw_oldboy.html rkoxkozsfs_oldboy.html
inpdcqsmfo_oldboy.html paoreutqqd_oldboy.html sksdayeamk_oldboy.html
[root@web01 /oldboy]# rename "oldboy.html" "oldgirl.HTML" *html
[root@web01 /oldboy]# ls
fzewmfbowb_oldgirl.HTML kfixfkghqz_oldgirl.HTML qaxuezrdyh_oldgirl.HTML vkftijhssz_oldgirl.HTML
ibcmutcmyj_oldgirl.HTML ovqxxevhlw_oldgirl.HTML rkoxkozsfs_oldgirl.HTML
inpdcqsmfo_oldgirl.HTML paoreutqqd_oldgirl.HTML sksdayeamk_oldgirl.HTML
Path=/oldboy
[ -d $Path ] || mkdir $Path
cd $Path
a=`ls *.html|wc -l` >/dev/null
for file in `ls`
do
if [ $a -ne 0 ]
then
echo `ls *.html|awk -F '_' '{print "mv",$0,$1"_oldgirl.HTML"}'|bash` >/dev/null
else
echo `ls *.HTML|awk -F '_' '{print "mv",$0,$1"_oldboy.html"}'|bash` >/dev/null
fi
done
ls *.html|awk -F '_' '{print "mv",$0,$1"_oldgirl.HTML"}'|bash
11.企业Shell面试题8:筛选符合长度的单词案例
利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题)。
I am oldboy teacher welcome to oldboy training class
解答:
本题的详细答案见第13章范例13_4,此处仅作为Shell案例集中收集整理。
1)字符串长度
[root@web01 /server/scripts]# oldboy="I am oldboy."
[root@web01 /server/scripts]# echo {oldboy}|wc -L
12
[root@web01 /server/scripts]# expr length "oldboy|awk '{print length}'
12
[root@web01 /server/scripts]# echo 0)}'
12
答案:
for n in I am oldboy teacher welcome to oldboy training class
do
if [ ${#n} -le 6 ]
then
echo $n
fi
done
12.
1、10位小写字母随机数:
[root@web01 /server/scripts]# openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11
vtrowtjefi
2、命令行手工搞定一个
[root@web01 /server/scripts]# random=`openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11`
[root@web01 /server/scripts]# echo $random
qvnprjvpey
[root@web01 /server/scripts]# echo $random
qvnprjvpey
[root@web01 /server/scripts]# random=`openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11`
[root@web01 /server/scripts]# echo $random
ftlhpzuvcg
[root@web01 /server/scripts]# touch ${random}_oldboy.html
[root@web01 /server/scripts]# random=`openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11`
[root@web01 /server/scripts]# touch ${random}_oldboy.html
3、搞定多个脚本for循环
[root@web01 /server/scripts]# vim 19_1_1.sh
#!/bin/bash
##############################################################
# File Name: 19_1_1.sh
# Version: V1.0
# Author: oldboy
# Organization: www.oldboyedu.com
##############################################################
Path=/oldboy
[ -d $Path ] || mkdir $Path
for n in {1..10}
do
random=`openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-11`
touch $Path/${random}_oldboy.html
done
[root@web01 /server/scripts]# sh 19_1_1.sh
[root@web01 /server/scripts]# ls /oldboy/
hdsktbnueg_oldboy.html ndiwjuwlmc_oldboy.html sofpatdies_oldboy.html xatlfezzzq_oldboy.html
ierjzagjho_oldboy.html phsdsrbrej_oldboy.html vlamkzfoac_oldboy.html
knsujjmavg_oldboy.html rhobejmimj_oldboy.html wxmrqzxjcz_oldboy.html
13.随机数:
1、openssl随机数
[root@web01 /server/scripts]# openssl rand -base64 8|cut -c 1-8
M7R3cvSl
[root@web01 /server/scripts]# openssl rand -base64 8|cut -c 1-8
lqknKo1o
2、简单random随机数
[root@web01 /server/scripts]# echo $RANDOM
28127
RANDOM Each time this parameter is referenced, a random integer between 0 and 32767 is generated. The
sequence of random numbers may be initialized by assigning a value to RANDOM. If RANDOM is
unset, it loses its special properties, even if it is subsequently reset.
3、时间随机数
[root@web01 /server/scripts]# date +%N
783556744
[root@web01 /server/scripts]# date +%N|md5sum|cut -c 5-13
c2ceaa04c
4、
[root@web01 /server/scripts]# head /dev/urandom|cksum|md5sum
f448a3b537ca1d8883079efc12705282 -
[root@web01 /server/scripts]# head /dev/urandom|cksum|md5sum
ef8bfd1604c04d0665c80741e5a6154d -
5、
[root@web01 /server/scripts]# cat /proc/sys/kernel/random/uuid
4c2c10a8-e340-48e8-a61e-65b052fe1ea8
[root@web01 /server/scripts]# cat /proc/sys/kernel/random/uuid
23fccdff-cae2-472b-8d26-65403ff8efe4
6、
mkpasswd命令依赖于数据包expect,因此必须通过yum install expect -y命令先安装该数据包。