1、写一个脚本,执行后,打印一行提示“Please input a number:",要求用户输入数值,然后打印出该数值,然后再次要求用户输入数值。直到用户输入"end"停止。
#!/bin/bash
while :
do
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "请输入一个纯数字."
continue
fi
if echo $n |grep -qi 'end'
then
exit
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "请输入一个纯数字."
continue
else
echo "你输入的数字是: $n"
continue
fi
done
2、请仔细查看如下几个数字的规律,并使用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
3、使用传参的方法写个脚本,实现加减乘除的功能。
例如: sh a.sh 1 2,这样会分别计算加、减、乘、除的结果。
要求:
- 脚本需判断提供的两个数字必须为整数
- 当做减法或者除法时,需要判断哪个数字大,减法时需要用大的数字减小的数字,除法时需要用大的数字除以小的数字,并且结果需要保留两个小数点。
#! /bin/bash
if [[ $1 =~ ^[0-9] ]] && [[ $2 =~ ^[0-9] ]]
then
a=`echo "scale=2;$1+$2" | bc`
echo $a
if [ $1 > $2 ]
then
b=`echo "scale=2;$1-$2" | bc`
echo $b
else
b=`echo "sacle=2;$2-$1" | bc`
echo $b
fi
c=`echo "scale=2;$1*$2" | bc`
echo $c
if [ $1 > $2 ]
then
d=`echo "scale=2;$1/$2" | bc`
echo $d
else
d=`echo "scale=2;$2/$1" | bc`
echo $d
fi
else
echo "请跟两个整数为参数"
fi
4、需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!并且每隔半小时把不再发起请求或者请求量很小的ip给解封。
假设:
(1). 一分钟内请求量高于100次的IP视为不正常请求。
(2). 访问日志路径为/data/logs/access_log。
(3). 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)”
#!/bin/bash
block_ip()
{
t1=`date -d "-1 min" +%Y:%H:%M`
log=/data/logs/access_log
egrep "$t1:[0-9]+" $log > /tmp/tmp_last_min.log
awk '{print $1}' /tmp/tmp_last_min.log |sort -n |uniq -c|sort -n |awk '$1>100 {print $2}' > /tmp/bad_ip.list
n=`wc -l /tmp/bad_ip.list|awk '{print $1}'`
if [ $n -ne 0 ]
then
for ip in `cat /tmp/bad_ip.list`
do
iptables -I INPUT -s $ip -j REJECT
done
fi
}
unblock_ip()
{
iptables -nvL INPUT|sed '1d' |awk '$1<5 {print $8}' > /tmp/good_ip.list
n=`wc -l /tmp/good_ip.list|awk '{print $1}'`
if [ $n -ne 0 ]
then
for ip in `cat /tmp/good_ip.list`
do
iptables -D INPUT -s $ip -j REJECT
done
fi
iptables -Z
}
t=`date +%M`
if [ $t == "00" ] || [ $t == "30" ]
then
unblock_ip
block_ip
else
block_ip
fi
5、写一个脚本: 计算100以内所有能被3整除的正整数的和
#!/bin/bash
sum=0
for i in `seq 1 100`
do
j=$[$i%3]
if [ $j -eq 0 ]
then
sum=$[$sum+$i]
fi
done
echo $sum
6、在服务器上,写一个监控脚本,要求如下:
(1) 每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
(2)若没有正常启动还需再一次启动,最大不成功数超过5次则需要立即发邮件通知管理员,并且以后不需要再检测!
(3)如果启动成功后,1分钟后再次检测httpd进程数,若正常则重复之前操作(每隔10s检测一次),若还是大于等于500,那放弃重启并需要发邮件给管理员,然后自动退出该脚本。假设其中发邮件脚本为之前使用的mail.py
#!/bin/bash
check_service()
{
n=0
for i in `seq 1 5`
do
/usr/local/apache2/bin/apachectl restart 2>/tmp/apache.err
if [ $? -ne 0 ]
then
n=$[$n+1]
else
break
fi
done
if [ $n -eq 5 ]
then
##下面的mail.py参考https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
python mai.py "123@qq.com" "httpd service down" `cat /tmp/apache.err`
exit
fi
}
while true
do
t_n=`ps -C httpd --no-heading |wc -l`
if [ $t_n -ge 500 ]
then
/usr/local/apache2/bin/apachectl restart
if [ $? -ne 0 ]
then
check_service
fi
sleep 60
t_n=`ps -C httpd --no-heading |wc -l`
if [ $t_n -ge 500 ]
then
python mai.py "123@qq.com" "httpd service somth wrong" "the httpd process is busy."
exit
fi
fi
sleep 10
done
7、写一个支持选项的增加或删除用户的shell脚本,具体要求如下:
(1) 只支持三个选项:’–del’,’–add’,’–help’,输入其他选项报错。
(2) 使用’–add’时,需要验证用户名是否存在,存在则反馈存在,且不添加。 不存在则创建该用户,需要设置与该用户名相同的密码。
(3) 使用’–del’时,需要验证用户名是否存在,存在则删除用户及其家目录。不存在则反馈该用户不存在。
(4) --help选项反馈出使用方法。
(5) 能用echo $?检测脚本执行情况,成功删除或添加用户为0,不成功为非0正整数。
(6) 能以英文逗号分割,一次性添加或者删除多个用户。例如 adddel.sh --add user1,user2,user3
#!/bin/baash
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo "Wrong, use bash $0 --add username, or bash $0 --del username or bash $0 --help"
exit
fi
ex_user()
{
if ! id $1 2>/dev/null >/dev/null
then
useradd $1 && echo "$1 add successful."
else
echo $1 exist.
fi
}
notex_user()
{
if id $1 2>/dev/null >/dev/null
then
userdel $1 && echo "$1 delete successful."
else
echo $1 not exist.
fi
}
case $1 in
--add)
if [ $# -eq 1 ]
then
echo "Wrong, use bash $0 --add user or bash $0 --add user1,user2,user3..."
exit
else
n=`echo $2| awk -F ',' '{print NF}'`
if [ $n -gt 1 ]
then
for i in `seq 1 $n`
do
username=`echo $2 |awk -v j=$i -F ',' '{print $j}'`
ex_user $username
done
else
ex_user $2
fi
fi
;;
--del)
if [ $# -eq 1 ]
then
echo "Wrong, use bash $0 --del user or bash $0 --del user1,user2,user3..."
exit
else
n=`echo $2| awk -F ',' '{print NF}'`
if [ $n -gt 1 ]
then
for i in `seq 1 $n`
do
username=`echo $2 |awk -v j=$i -F ',' '{print $j}'`
notex_user $username
done
else
notex_user $2
fi
fi
;;
--help)
if [ $# -ne 1 ]
then
echo "Wrong, use bash $0 --help"
exit
else
echo "Use bash $0 --add username or bash $0 --add user1,user2,user3... add user."
echo " bash $0 --del username -r bash $0 --del user1,user2,user3... delete user."
echo " bash $0 --help print this info."
fi
;;
*)
echo "Wrong, use bash $0 --add username, or bash $0 --del username or bash $0 --help"
;;
esac
8、添加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。
提示:
(1)随机密码使用命令 mkpasswd
(2)在脚本中给用户设置密码,可以使用echo 然后管道passwd命令
#!/bin/bash
for i in `seq -w 00 09`
do
useradd user_$i
p=`mkpasswd -l 10 -s 0 `
echo "user_$i $p" >> /tmp/pass.tmp
echo $p |passwd --stdin user_$i
done
9、假设,当前MySQL服务的root密码为123456,写脚本检测MySQL服务是否正常(比如,可以正常进入mysql执行show processlist),
并检测一下当前的MySQL服务是主还是从,如果是从,请判断它的主从服务是否异常。如果是主,则不需要做什么。
#!/bin/bash
mysql="/usr/local/mysql/bin/mysql -uroot -p123456"
if ! $mysql -e "show processlist" >/dev/null 2>/dev/null
then
echo "MySQL service is down."
exit
else
$mysql -e "show slave status\G" 2>/dev/null >/tmp/slave.stat
n=`wc -l /tmp/slave.stat|awk '{print $1}'`
if [ $n -eq 0 ]
then
echo "This is master."
else
echo "This is slave."
egrep 'Slave_IO_Running:|Slave_SQL_Running:'/tmp/slave.stat|awk -F ': ' '{print $2}' > /tmp/SQL.tmp
if grep -qw "No" /tmp/SQL.tmp
then
echo "The slave is down."
fi
fi
fi
10、写一个脚本实现如下功能:
输入一个数字,然后运行对应的一个命令。
显示命令如下:
cmd meau* 1 - date 2 - ls 3 - who 4 - pwd
当输入1时,会运行date, 输入2时运行ls, 以此类推。
#!/bin/bash
echo "*cmd meau** 1 - date 2 - ls 3 - who 4 - pwd"
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "请输入一个纯数字,范围1-4."
exit
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "请输入一个纯数字,范围1-4."
exit
fi
case $n in
1)
date
;;
2)
ls
;;
3)
who
;;
4)
pwd
;;
*)
echo "请输入1-4的数字"
;;
esac
11、写一个脚本判断你的Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务,是httpd呢还是nginx又或者是其他的什么
#!/bin/bash
n=`netstat -lntp |grep ':80 '|wc -l`
if [ $n -eq 0 ]
then
echo "It not listen port 80"
else
ser=`netstat -lntp |grep ':80 '|awk -F '/' '{print $NF}'|sed 's/ //g'`
echo "It is listenning port 80, and the service is $ser."
fi
12、用shell打印下面这句话中字母数小于6的单词。
Bash also interprets a number of multi-character options.
#!/bin/bash
c="Bash also interprets a number of multi-character options."
n=`echo $c|awk -F '[ +-.]' '{print NF}'`
for ((i=1;i<$n;i++))
do
l=`echo $c|awk -F '[ +-.]' -v j=$i '{print $j}'|wc -L`
if [ $l -lt 6 ]
then
echo $c|awk -F '[ +-.]' -v j=$i '{print $j}'
fi
done
13、一台机器负载高,top查看有很多sh的进程,然后top -c查看可以看到对应的进程命令是sh -c /bin/clearnen.sh 。经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有sh的进程。
#!/bin/bash
for pid in `ps aux |grep clearnen.sh |awk '{print $2}'`
do
echo $pid
kill -9 $pid
done
14、把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。
#!/bin/bash
sed -n '1,5'p 1.txt |sed '/[a-zA-Z]/d'
sed '1,5d' 1.txt |sed '1,5s/[a-zA-Z]//g'
15、写一个脚本,检测你的网络流量,并记录到一个日志里。需要按照如下格式,并且一分钟统计一次(只需要统计外网网卡,假设网卡名字为eth0):
2017-08-04 01:11
eth0 input: 1000bps
eth0 output : 200000bps
2017-08-04 01:12
eth0 input: 1000bps
eth0 output : 200000bps
提示:使用sar -n DEV 1 59 这样可以统计一分钟的平均网卡流量,只需要最后面的平均值。另外,注意换算一下,1Byte=8bit
#!/bin/bash
logdir=/tmp/sar_log
file=$logdir/`date +%d%H`.log
t=`date +"%F %H:%M"`
[ -d $logdir ] || mkdir -p $logdir
LANG=en
sar -n DEV 1 5 |grep eth0 |grep "Average" > /tmp/sar.tmp
exec >>$file
echo "$t"
awk '{print "eth0 input:",$5*8000"bps""\n""eth0 output:",$6*8000"bps"}' /tmp/sar.tmp
echo "#### ###################"