shell脚本案例(初级)

案例一:批量生产随机字符文件名

使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy,名称示例如下:xxxxxxxxxx_oldboy.html

#!/bin/bash
#
DIR=/oldboy
[ -d /oldboy ] || mkdir $DIR
for i in {
    
    1..10}
do
  filename=`head /dev/urandom  | md5sum |tr [0-9] [a-z] | cut -c 1-10`
  touch $DIR/${
    
    filename}_oldboy.html
done
exit 0  

案例二:批量改文件名

将上面案例中结果文件名中的oldboy字符串全部改成oldgirl(最好用for循环实现),并且将扩展名html全部改成大写。

#!/bin/bash
#
DIR=/oldboy
cd $DIR
file_list=(`ls *oldboy.html`)
filenum=${
    
    #file_list[@]}
file=0
while [ $file -lt $filenum ]
do
  newfilename=${
    
    file_list[$file]%%_*}_oldgirl.HTML
  mv ${
    
    file_list[$file]} $newfilename
  let "file += 1"
done
exit 0

案例三:批量创建特殊要求用户

批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码为随机数,要求字符和数字等混合)。

#!/bin/bash
#
for i in oldboy{
    
    01..10}
do
  useradd $i &> /dev/null
  if [ $? -eq 0 ];then
    password="`head /dev/urandom | md5sum | cut -c 1-10`"
    echo $i  $password >> /tmp/user_passwd.log
    echo $password | passwd --stdin $i &> /dev/null
    echo "$i  创建成功"
  else
    echo "创建用户失败"  
  fi
done
exit 0

案例四:扫描网络内存活主机

写一个Shell脚本,判断192.168.1.0/24网络里,当前在线的IP有哪些。

#!/bin/bash
#
for i in 192.168.1.{
    
    1..254}
do
  ping -c 2 -w 2 $i &> /dev/null
  if [ $? -eq 0 ];then
    echo "$i  在线"
  else
    echo "$i  未在线"
  fi
done
exit 0      

案例五:解决DOS

请根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100(读者根据实际情况设定),即调用防火墙命令封掉对应的IP。
防火墙命令为:iptables-I INPUT -s IP地址 -j DROP。

#!/bin/bash
#
LOG=/usr/local/nginx/logs/access.log
cat /dev/null > /tmp/rizhi.log
awk '{print $1}' $LOG | sort -nr | uniq -c > /tmp/rizhi.log
num=(`awk '{print $1}' /tmp/rizhi.log`)
IPADDR=(`awk '{print $2}' /tmp/rizhi.log`)
i=0
while [ $i -lt "${#num[@]}" ]
do
  if [ "${num[$i]}" -gt 100 ];then
    echo "存在恶意攻击ip: "${
    
    IPADDR[$i]}""
    #iptables-I INPUT -s "$IPADDR" -j DROP
  fi
  let "i += 1"
done
exit 0

案例六:MySQL数据库分库分表备份

#!/bin/bash
#
Mycmd="mysql -uroot -pZHHS_root11"
Mydump="mysqldump $Mycmd --all-databases "
DBlist=`$Mycmd -e "show databases;" | sed '1d' | egrep -v "_schema|mysql"`
[ -d /tmp/mysql_bak/ ] || mkdir -p /tmp/mysql_bak

for database in $DBlist
do
  TableList=`$Mycmd -e "show tables from $database;" | sed 1d`
  for table in $TableList
  do
    [ -d /tmp/mysql_bak/${
    
    database} ] || mkdir -p /tmp/mysql_bak/${
    
    database}
    $Mydump $database $table > /tmp/mysql_bak/${
    
    database}/${
    
    table}_$(date +%F).sql
  done
  echo -e "\033[32m mysqldump $database is ok !!! \033[0m"
done
exit 0    

案例七:筛选符合长度的单词

利用bash for循环打印下面这句话中字母数不大于6的单词

I am oldboy teacher welcome to oldboy trainingclass

#!/bin/bash
#
str_list=(I am oldboy teacher welcome to oldboy trainingclass)
num=${
    
    #str_list[@]}

i=0
while [ $i -lt $num ]
do
  if [ ${
    
    #str_list[$i]} -le 6 ];then
    echo ${
    
    str_list[$i]}
  fi
  let "i += 1"
done
exit 0    

案例八:比较整数大小

开发shell脚本分别实现以脚本传参及read读入的方式比较2个整数大小。
注意:一共是开发2个脚本。当用脚本传参以及read读入的方式需要对变量是否为数字、并且传参个数不对给予提示。

传参脚本

#!/bin/bash
#
E_ARG=65

if [ $# -eq 2 ];then
  true
else
  echo "用法:`basename $0` number1 number2"  
  exit $E_ARG
fi

a=`let "$1 * $2"`  &> /dev/null
if [ $? -eq 0 ];then
  if [ $1 -gt $2 ];then
    echo "$1 大于 $2"
  elif [ $1 -eq $2 ];then
    echo "$1 等于 $2"
  else
    echo "$1 小于 $2"  
  fi
else  
  echo "用法:`basename $0` number1 number2"
  exit 66
fi
exit 0

read脚本

#!/bin/bash
#
read -t 10 -p "请输入第一个数字(您有10秒的时间) " num1
if [ -z $num1 ];then
  echo;echo"超时"
  exit 65
fi  
read -t 10 -p "请输入第二个数字(您有10秒的时间) " num2
if [ -z $num2 ];then
  echo;echo"超时"
  exit 65
fi

a=`let "$num1 * $num2"`  &> /dev/null
if [ $? -eq 0 ];then
  if [ $num1 -gt $num2 ];then
    echo "$num1 大于 $num2"
  elif [ $num1 -eq $num2 ];then
    echo "$num1 等于 $num2"
  else
    echo "$num1 小于 $num2"  
  fi
else  
  echo "请输入阿拉伯数字"
  exit 66
fi
exit 0

案例九:菜单自动化软件部署

打印选择菜单,按照选择一键安装不同的Web服务
要求:
1、当用户输入1时,输出“startinstalling lamp.提示”然后执行/tmp/lamp.sh,脚本内容输出"lampis installed"后退出脚本,工作中就是正式lamp一键安装脚本。
2、当用户输入2时,输出“startinstalling lnmp.提示” 然后执行/tmp/lnmp.sh输出"lnmpis installed"后退出脚本,工作中就是正式lnmp一键安装脚本。
3、当输入3时,退出当前菜单及脚本。
4、当输入任何其它字符,给出提示“Input error”后退出脚本。
5、要对执行的脚本进行相关的条件判断,例如:脚本文件是否存在,是否可执行等判断,尽量用上前面讲解的知识点。

#!/bin/bash
#
echo "1.[install lamp]
2.[install lnmp]
3.[exit]
"
read -t 10 -p "请选择要操作的步骤(1/2/3),您有10秒的时间 " num
if [ -z "$num" ];then
  echo;echo "超时"
  exit 63
fi
   
case $num in
1)
  if [ -e /tmp/lamp.sh ];then
    if [ -x /tmp/lamp.sh ];then
      /tmp/lamp.sh
      echo "lampis installed"
    else
      echo "/tmp/lamp.sh 没有权限"  
    fi
  else
    echo "/tmp/lamp.sh 不存在"  
  fi
  ;;
2)
  if [ -e /tmp/lnmp.sh ];then
    if [ -x /tmp/lnmp.sh ];then
      /tmp/lnmp.sh
      echo "lnmpis installed"
    else
      echo "/tmp/lnmp.sh 没有权限"  
    fi
  else
    echo "/tmp/lnmp.sh 不存在"  
  fi
  ;;
3)
  exit 64;;
*)
  echo "Input error"
  exit 65
esac
exit 0

案例十:Web及MySQL服务异常监测

用if条件语句实现对Nginx服务是否正常进行检测,如果服务未启动,则启动相应服务。

#!/bin/bash
#
NGINX=`ss -natpul | grep nginx | wc -l`
if [ $NGINX -gt 0 ];then
  echo "nginx is running!"
  exit 0
else
  echo "nginx is not running!"
fi

echo "
1.[start]
2.[exit]
"

read -t 10 -p "是否启动nginx(1/2)?您有10秒的时间考虑 " action
if [ -z "$action" ];then
  echo "超时,默认启动nginx"
  /usr/local/nginx/sbin/nginx start
fi

case $action in
1)
  echo "即将启动nginx"
  /usr/local/nginx/sbin/nginx start
  ;;
2)
  exit;;
*)
  echo "Input error"
  exit 65
esac
exit 0

案例十一:防篡改检测与报警

监控web站点目录(/var/html/www)下所有文件是否被恶意篡改,如果有就打印改动的文件名(发邮件)。

#!/bin/bash
#
html_file=(`find /var/html/www -type f`)
html_file_sum=${
    
    #html_file[@]}
md5_dir=/tmp/checkdir
[ ! -d $md5_dir ] && mkdir -p $md5_dir

i=0
while [ $i -lt $html_file_sum ]
do
  md5sum ${
    
    html_file[$i]} >> $md5_dir/o.txt
  let "i += 1"
done

md5sum -c $md5_dir/o.txt | grep FAILED >> $md5_dir/n.txt
if [ -s $md5_dir/n.txt ];then
  echo "`cat $md5_dir/n.txt | uniq`" | mail -s "`date +"%F %H:%M:S"` WEB 被篡改" [email protected]
  #echo "`awk -F ":" '{print $1}' $md5_dir/n.txt | uniq ` : 被篡改"
else
  true
  #echo "正常"
fi
exit 0

案例十二:开发nginx服务启动脚本

要求:
1.要使用系统函数库技巧。
2.要用函数,不能一坨command的方式。
3.可被chkconfig管理。

#!/bin/bash
#/etc/init.d/nginx
#
#:如果需要被chkconfig管理,就必须添加一下面两行
# chkconfig: - 88 35   
# description: nginx is a World Wide Web server. It is used to serve 
#
NGINXBIN=/usr/local/nginx/sbin/nginx
TIMEOUT=5

NginxStart()
{
    
    
    NGINXPID=`ss -natpul | grep nginx`
    STARTTIME=0
    if [ -z "$NGINXPID" ];then
      echo "soon start is NGINX"
      $NGINXBIN
      while [ $STARTTIME -le $TIMEOUT ]
      do
        NginxPid=`ss -natpul | grep nginx`
        if [ ! -z "$NginxPid" ];then
          echo "NGINX start OK"
          break
        else
          sleep 1
          let "STARTTIME += 1"
        fi
      done
    elif [ $STARTTIME -gt $TIMEOUT ];then
      echo "ERROR:nginx start timeout"
      exit 66
    else
      echo "NGINX is running"
    fi  
}

NginxStop()
{
    
    
    NGINXPID=`ss -natpul | grep nginx`
    STOPTIME=0
    if [ ! -z "$NGINXPID" ];then
      echo "soon stop is NGINX"
      $NGINXBIN -s stop
      while [ $STOPTIME -le $TIMEOUT ]
      do
        NginxPid=`ss -natpul | grep nginx`
        if [ -z "$NginxPid" ];then
          echo "NGINX stop OK"
          break
        else
          let "STOPTIME += 1"
          sleep 1
        fi  
      done
    elif [ $STOPTIME -gt $TIMEOUT ];then
      echo "ERROR:nginx stop timeout"
      exit 67
    else
      echo "nginx is not running"  
    fi  
}

case $1 in
start)
  NginxStart
  ;;
stop)
  NginxStop
  ;;
restart)
  NginxStop
  NginxStart
  ;;
*)
  echo "USAGE: `basename $0` [start|stop|restart]"  
esac
exit 0
chmod + x /etc/init.d/nginx
chkconfig --add nginx

案例十三:学生抓阄

1、执行脚本后,想去的同学输入英文名字全拼,产生随机数1-99之间的数字,数字大的去参加项目实践,前面已经抓到的数字,下次不能再出现相同数字。
2、第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入。

#!/bin/bash
#
FILE=/tmp/temp.txt   #保存记录的文件
[ -f $FILE ] || touch $FILE
STUDENT=3   #被选中的人数

input()
{
    
    
    while true
   do
     read -p "请输入你名字的全拼(输入q/Q退出):" name
     check_name=`awk '{print $1}' $FILE |grep ^"$name"$`
     let "$name / 1" &> /dev/null
     if [ $? -eq 0 ];then   #这里判断输入的名字不能为一个整数(小数的判断还未实现)
       echo "您输入的有误,"$name"不是一个名字。"
       continue
     fi
       
     if [ -z "$name" ];then
       echo "您输出的为空,请重新输入"
       continue
     fi
      
     if [ ! -z "$check_name" ];then
       echo "sorry,您已经输入过了!"
       continue
     fi
     
     number=$((RANDOM%100))
     check_number=`awk '{print $3}' $FILE |grep ^"$number"$`
     if [ "$name" == q -o "$name" == Q ];then
        break
     elif [ -z "$check_number" ];then
       echo "$name ===> $number"  >> $FILE
     else
       echo "出现相同的大小,请重新输入您的名字"
       continue
     fi  
   done
}

output()
{
    
    
    full_list=`sort -nr -k 3 $FILE`
    select_list=`sort -nr -k 3 $FILE | head -"$STUDENT"`
    echo "+-------++-------++-------+"
    echo "被选中的同学为:"
    echo "$select_list"
    echo "+-------++-------++-------+"
    echo;echo "所有参与学生的列表:"
    echo "$full_list"
}

main()
{
    
    
    input
    output
}
main
exit 0

案例十四:破解RANDOM随机数案例

已知下面的字符串是通过RANDOM随机数变量md5sum后,再截取一部分连续字符串的结果,请破解这些字符串对应的使用md5sum处理前的RANDOM对应的数字。

21029299
00205d1c
a3da1677
1f6d12dd
890684b

#!/bin/bash
#
for i in {
    
    0..50000}
do
  echo "$i:$(echo $i | md5sum)" >> /tmp/passbook.txt
done

egrep '21029299|00205d1c|a3da1677|1f6d12dd|890684b' /tmp/passbook.txt
exit 0

案例十五:批量检查多个网站地址是否正常

要求:
1、使用shell数组方法实现,检测策略尽量模拟用户访问。
2、每10秒钟做一次所有的检测,无法访问的输出报警。
3、待检测的地址如下

http://blog.oldboyedu.com
http://blog.etiantian.org
http://oldboy.blog.51cto.com
http://10.0.0.7

#!/bin/bash
#
url_list=(
http://blog.oldboyedu.com
http://blog.etiantian.org
http://oldboy.blog.51cto.com
http://10.0.0.7
)

for i in ${
    
    url_list[@]}
do
  prot=`curl -I -s -w "%{http_code}\n" "$i" -o /dev/null`
  #STATUS=`curl -s -I "$i" | sed -n '/HTTP/p' | awk '{print $2}'`   #这个也可以
  if [ $port -eq 200 ];then
  #if [ $STATUS -eq 200 ];then
    echo "$i is OK"
  else
    echo "warning: $i breakdown"  
  fi
done
exit 0  

案例十六:单词及字母去重排序

要求:
1、按单词出现频率降序排序!
2、按字母出现频率降序排序!

the squid project provides a number ofresources to assist users design,implement and support squid installations.Please browse the documentation and support sections for more infomation,byoldboy training.

#!/bin/bash
#
STRING="the squid project provides a number ofresources to assist users design,implement and support squid installations.Please browse the documentation and support sections for more infomation,byoldboy training."
words()
{
    
    
    echo "$STRING" | sed 's/[^a-zA-Z]/\n/g' | grep -v "^$" | sort | uniq -c | sort -rn -k 1
}

letters()
{
    
    
    echo "$STRING" | grep -o . | egrep -v "^$|[^a-z|A-Z]" | sort | uniq -c | sort -nr -k 1
}
#grep -o    :只显示行匹配模式的一部分
#grep -o .   :匹配任意一个字符
#grep -o ..   :会发生什么?
#grep -o ...   :多试试就会理解

case $1 in
word)
  words
  ;;
letter)
  letters
  ;;
*)
  echo "USAGE:`basename $0` [word|letter]"
esac
exit 0

案例十七:编写正或长方形图形案例

#!/bin/bash
#
read -p "Please Enter a number:" num
for ((i=1;$i<=$num;i++))
do
  for ((j=1;j<=$((2*$num));j++))
  do
    echo -n "+"
  done
  echo
done
exit 0    

案例十八:编写等腰三角形图形字符案例

#!/bin/bash
#
read -p "Please Enter a number:" num
for ((i=1;i<=$num;i++))
do
  for ((h=$((2*$num-2*$i));h>=0;h--))
  do
    echo -n " "
  done
  for ((j=1;j<=$((2*$i-1));j++))
  do
    echo -n " *"
  done
  echo
done
exit 0      

案例十九:编写直角梯形图形字符案例

#!/bin/bash
if [[ -n $1 ]] && [[ -n $2 ]];then
  for ((i=$1;$i<=$2;i++))
  do
    for ((j=1;j<=$i;j++))
    do
      echo -e "*\c" #不换行
    done
    echo
  done
else
  echo "No given two int arguments, please use $0 5 6|6 8!"
fi
exit 0

参考的文章链接:https://blog.51cto.com/13520779/2093146

猜你喜欢

转载自blog.csdn.net/qq_43584691/article/details/109646408