21、题目要求 :计算数字个数
计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下: 12aa*lkjskdj alskdflkskdjflkjj 我们脚本名字为 ncount.sh, 运行它时: bash ncount.sh a.txt 输出结果应该为: 2 0 sum:2
【核心要点】
sed 把非数字字符删除,计算长度
for循环计算总和
参考答案
#!/bin/bash
sum=0
while read line
do
line_n=`echo $line|sed 's/[^0-9]//g'|wc -L`
echo $line_n
sum=$[$sum+$line_n]
done < $1
echo "sum:$sum"
案例 :
# for i in 'echo -e "123456\nabc 123"'; do echo $i; done
123456
abc
123
注意 :
echo $line|sed 's/[^0-9]//g'|wc -L #非数字的字符,全部清空并计算一下长度。
sum=$[$sum+$line_n] #计算sum的值
22、题目要求 :对比文件差异
有两台Linux服务器A和B,假如A可以直接ssh到B,不用输入密码。A和B都有一个目录叫做/data/web/ 这下面有很多文件,
当然我们不知道具体有几层子目录,假若之前A和B上该目录下的文件都是一模一样的。
但现在不确定是否一致了。固需要我们写一个脚本实现这样的功能,检测A机器和B机器/data/web/目录下文件的异同,我们以A机器上的文件作为标准。
比如,假若B机器少了一个a.txt文件,那我们应该能够检测出来,或者B机器上的b.txt文件有过改动,我们也应该能够检测出来(B机器上多了文件不用考虑)。
【核心要点】
md5sum file
参考答案
#!/bin/bash
#dir=/data/web
dir=/tmp
[ -f /tmp/md5.list ] && rm -f /tmp/md5.list
find $dir/ -type f > /tmp/file.list
while read line
do
md5sum $line >> /tmp/md5.list
done < /tmp/file.list
scp /tmp/md5.list B:/tmp/
[ -f /tmp/check_md5.sh ] && rm -f /tmp/check_md5.sh
cat >/tmp/check_md5.sh << EOF
#!/bin/bash
dir=/data/web
n=\`wc -l /tmp/md5.list|awk '{print \$1}'\`
for i in \`seq 1 \$n\`
do
file_name=\`sed -n "\$i"p /tmp/md5.list |awk '{print \$1}'\`
md5=\`sed -n "\$i"p /tmp/md5.list|awk '{print \$2}'\`
if [ -f \$file_name ]
then
md5_b=\`md5sum \$file_name\`
if [\$md5_b != \$md5 ]
then
echo "\$file_name changed."
fi
else
echo "\$file_name lose."
fi
done
EOF
scp /tmp/check_md5.sh B:/tmp/
ssh B "/bin/bash /tmp/check_md5.sh"
案例 :
在A机器登录B机器
# myssh aming "ls /tmp/ wc -l" #查看阿明机器的秘钥,远程登录b机器,并查看b机器文件 ,形式 是ssh +主机名或者主机IP地址 +文件路径
直接登录B机器
# myssh aming #登录B机器
注意 :
scp /tmp/md5.list B:/tmp/
[ -f /tmp/check_md5.sh ] && rm -f /tmp/check_md5.sh #从A机器上面拷贝/tmp/md5.list到B机器的tmp目录下,如果B机器存在/tmp/check_md5.sh,就删/tmp/check_md5.sh除/tmp/check_md5.sh
# cat > 2.txt <<EOF #往2.txt文件中,写入1,2,3
>1
>2
>3
> EOF
23、题目要求 :检测网卡流量
写一个脚本,检测你的网络流量,并记录到一个日志里。需要按照如下格式,并且一分钟统计一次(只需要统计外网网卡,假设网卡名字为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
【核心要点】
sar命令
awk格式化输出
参考答案
#!/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 59 |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 "#### ###################"
案例 :
# sar -n DEV 1 5 #查看DEV网卡的流量 ,第五列是进入的流量rxkB/s
sar -n DEV 1 59 |grep eth0 |grep "Average" > /tmp/sar.tmp #每59秒,显示一次 Average,并写入/tmp/sar.tmp 文件中
注意 : 8bit = 1byte
10兆,单位 :bit
迅雷下载的单位 是 byte
100Mbit(100兆带宽) 单位 :12.5MByte/s
24、题目要求 : 杀进程
一台机器负载高,top查看有很多sh的进程,然后top -c查看可以看到对应的进程命令是sh -c /bin/clearnen.sh 。
经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有sh的进程。
【核心要点】
kill -9 pid
参考答案
#!/bin/bash
for pid in `ps aux |grep clearnen.sh |awk '{print $2}'`
do
echo $pid
kill -9 $pid
done
案例 :
查看系统的pid进程数
杀死pid进程数
注意 :使用 -9 杀进程 会导致数据库数据丢失
25、题目要求 :判断web服务(80端口)
写一个脚本判断你的Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务,是httpd呢还是nginx又或者是其他的什么?
【核心要点】
netstat -lntp |grep ':80 '
参考答案
#!/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
案例 :
# netstat -lntp #查看TCP监听的端口
#netstat -lntp |grep ':80 ' #精准查询80端口
#netstat -lntp |grep ':80 ' |awk -F '/' '{print $NF}' #精准查询80端口使用的进程
也可以使用lsof命令 查看端口信息(如果没有这个命令,使用yum install -y lsof安装)
注意 :
$n -eq #如果eq等于1,说明80,不存在
26、题目要求 : 监控mysql服务
假设,当前MySQL服务的root密码为123456,写脚本检测MySQL服务是否正常(比如,可以正常进入mysql执行show processlist),
并检测一下当前的MySQL服务是主还是从,如果是从,请判断它的主从服务是否异常。如果是主,则不需要做什么。
【核心要点】
mysql -uroot -p1234356 -e "show processlist"
show slave status
参考答案
#!/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
案例 :
# mysql -uroot -p123456 -e "show processlist" #查看数据库中的表,显示no,说明数据库有问题。
# mysql -uroot -p123456 -e "show slave status\G" #清空数据库中的表
注意 :
if grep -qw "No" /tmp/SQL.tmp #查找是否含有No的关键字,在/tmp/SQL.tmp
27、题目要求
写一个支持选项的增加或删除用户的shell脚本,具体要求如下:
- 只支持三个选项:'--del','--add','--help',输入其他选项报错。
- 使用'--add'时,需要验证用户名是否存在,存在则反馈存在,且不添加。 不存在则创建该用户,需要设置与该用户名相同的密码。
- 使用'--del'时,需要验证用户名是否存在,存在则删除用户及其家目录。不存在则反馈该用户不存在。
- --help选项反馈出使用方法。
- 能用echo $?检测脚本执行情况,成功删除或添加用户为0,不成功为非0正整数。
- 能以英文逗号分割,一次性添加或者删除多个用户。例如 adddel.sh --add user1,user2,user3
【核心要点】
case 判断
批量添加多用户,需要for循环
参考答案
#!/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
案例 :
28、题目要求
写一个脚本: 计算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
案例 :
29、题目要求
使用传参的方法写个脚本,实现加减乘除的功能。 例如: sh a.sh 1 2,这样会分别计算加、减、乘、除的结果。
要求:
- 脚本需判断提供的两个数字必须为整数
- 当做减法或者除法时,需要判断哪个数字大,减法时需要用大的数字减小的数字,除法时需要用大的数字除以小的数字,并且结果需要保留两个小数点。
参考答案
#!/bin/bash
is_nu()
{
n=`echo $1 |sed 's/[0-9]//g'`
if [ -n "$n" ]
then
echo "给出的参数必须是正整数"
exit
fi
}
if [ $# -ne 2 ]
then
echo "必须要输入两个参数"
exit
else
is_nu $1
is_nu $2
fi
big()
{
if [ $1 -gt $2 ]
then
echo $1
else
echo $2
fi
}
small()
{
if [ $1 -lt $2 ]
then
echo $1
else
echo $2
fi
}
add()
{
sum=$[$1+$2]
echo "$1+$2=$sum"
}
jian()
{
b=`big $1 $2`
s=`small $1 $2`
cha=$[$b-$s]
echo "$b-$s=$cha"
}
cheng()
{
ji=$[$1*$2]
echo "$1x$2=$ji"
}
chu()
{
b=`big $1 $2`
s=`small $1 $2`
v=`echo "scale=2;$b/$s"|bc`
echo "$b/$s=$v"
}
add $1 $2
jian $1 $2
cheng $1 $2
chu $1 $2
案例 :
30、题目要求
写一个脚本,执行后,打印一行提示“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
案例 :
来源 :https://github.com/aminglinux/shell100/blob/master/13.md