SHELL脚本编程循环篇-while循环
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.while循环的语法格式
while CONDITION; do 循环体 done 以上参数关键点说明: CONDITION: 循环控制条件,进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环。因此,CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正 进入条件: CONDITION为true 退出条件: CONDITION为false 其实也可以写成一行: [root@node101.yinzhengjie.org.cn ~]# i=1;while [ $i -le 100 ];do let sum+=i;let i++;done;echo sum=$sum sum=5050 [root@node101.yinzhengjie.org.cn ~]#
二.循环控制语句continue
while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done 使用场景: 用于循环体中,continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
[root@node101.yinzhengjie.org.cn ~]# cat shell/continue.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/continue.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** flag=true i=0 while [ $i -lt 10 ];do let i++ #如果"$i"的值为7,则跳过本次循环进行下一次循环 if [ $i -eq 7 ];then continue fi echo $i done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/continue.sh 1 2 3 4 5 6 8 9 10 [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# cat shell/continue.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/continue.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** flag=true i=0 while [ $i -lt 3 ];do let i++ for((j=1;j<=10;j++));do if [ $j -eq 7 ];then #退出到本层循环的上一轮循环 continue 2 fi echo j=$j done echo i=$i done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/continue.sh j=1 j=2 j=3 j=4 j=5 j=6 j=1 j=2 j=3 j=4 j=5 j=6 j=1 j=2 j=3 j=4 j=5 j=6 [root@node101.yinzhengjie.org.cn ~]#
三.循环控制语句break
while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
使用场景: 用于循环体中,break [N]:提前结束第N层循环,最内层为第1层
[root@node101.yinzhengjie.org.cn ~]# cat shell/break.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/continue.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** flag=true i=0 while [ $i -lt 10 ];do let i++ #如果"$i"的值为7,则直接跳出循环 if [ $i -eq 7 ];then break fi echo $i done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/break.sh 1 2 3 4 5 6 [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# cat shell/break.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/continue.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** flag=true i=0 while [ $i -lt 3 ];do let i++ for((j=1;j<=10;j++));do if [ $j -eq 7 ];then #退出本层循环的上一层循环 break 2 fi echo j=$j done echo i=$i done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/break.sh j=1 j=2 j=3 j=4 j=5 j=6 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
四.循环控制shift命令
shift [n]:
用于将参量列表 list 左移指定次数,缺省为左移一次。 参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift
[root@node101.yinzhengjie.org.cn ~]# cat shell/useradd.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/useradd.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** echo 1st arg is $1 echo 2st arg is $2 echo all args are $* shift echo shift echo 1st arg is $1 echo 2st arg is $2 echo all args are $* shift echo shift echo 1st arg is $1 echo 2st arg is $2 echo all args are $* [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/useradd.sh a b c d e f g 1st arg is a 2st arg is b all args are a b c d e f g shift 1st arg is b 2st arg is c all args are b c d e f g shift 1st arg is c 2st arg is d all args are c d e f g [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# cat shell/useradd.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/useradd.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** while true;do [ -z "$1" ] && break useradd $1 && echo "$1 is created." shift done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/useradd.sh a b c d e a is created. b is created. c is created. d is created. e is created. [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# tail -5 /etc/passwd a:x:1044:1044::/home/a:/bin/bash b:x:1045:1045::/home/b:/bin/bash c:x:1046:1046::/home/c:/bin/bash d:x:1047:1047::/home/d:/bin/bash e:x:1048:1048::/home/e:/bin/bash [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# vim shell/doit.sh [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat shell/doit.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/useradd.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** while [ $# -gt 0 ] # 也可以写出C语言风格:(( $# > 0 )) do echo $* shift done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/doit.sh {a..z} a b c d e f g h i j k l m n o p q r s t u v w x y z b c d e f g h i j k l m n o p q r s t u v w x y z c d e f g h i j k l m n o p q r s t u v w x y z d e f g h i j k l m n o p q r s t u v w x y z e f g h i j k l m n o p q r s t u v w x y z f g h i j k l m n o p q r s t u v w x y z g h i j k l m n o p q r s t u v w x y z h i j k l m n o p q r s t u v w x y z i j k l m n o p q r s t u v w x y z j k l m n o p q r s t u v w x y z k l m n o p q r s t u v w x y z l m n o p q r s t u v w x y z m n o p q r s t u v w x y z n o p q r s t u v w x y z o p q r s t u v w x y z p q r s t u v w x y z q r s t u v w x y z r s t u v w x y z s t u v w x y z t u v w x y z u v w x y z v w x y z w x y z x y z y z z [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
五.while循环的特殊用法(遍历文件的每一行)
while read line; do 循环体 done < /PATH/FROM/SOMEFILE
以上语法作用说明: 依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
[root@node101.yinzhengjie.org.cn ~]# while read line;do echo $line;done < /etc/fstab # # /etc/fstab # Created by anaconda on Mon Jul 8 16:22:49 2019 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 0 0 UUID=343e9f9c-8324-4918-a10d-541627af8e04 /boot xfs defaults 0 0 /dev/mapper/centos-home /home xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# cat shell/whileread.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/whileread.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** while read line;do uid=`echo $line |cut -d : -f 3` username=`echo $line |cut -d : -f 1` if [ $uid -ge 1000 ];then echo $username:$uid fi done < /etc/passwd [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/whileread.sh mysql:1000 yinzhengjie:1001 jason:1002 jason1:1003 jason2:1004 jason3:1005 jason4:1006 jason5:1007 jason6:1008 jason7:1009 jason8:1010 jason9:1011 jason10:1012 jason11:1013 jason12:1014 jason13:1015 jason14:1016 jason15:1017 jason16:1018 jason17:1019 jason18:1020 jason19:1021 jason20:1022 jason21:1023 jason22:1024 jason23:1025 jason24:1026 jason25:1027 jason26:1028 jason27:1029 jason28:1030 jason29:1031 jason30:1032 yinzhengjie1:1033 yinzhengjie2:1034 yinzhengjie3:1035 yinzhengjie4:1036 yinzhengjie5:1037 yinzhengjie6:1038 yinzhengjie7:1039 yinzhengjie8:1040 yinzhengjie9:1041 yinzhengjie10:1042 cracker:1043 a:1044 b:1045 c:1046 d:1047 e:1048 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# cat shell/check_disk.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/check_disk.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** warning=10 df | while read diskspace;do space=`echo $diskspace | sed -nr '/^/dev/sd/s#.* (.+)%.*#1#p'` disk=`echo $diskspace | sed -nr '/^/dev/sd/s#([^ ]+).*#1#p'` if [[ $space =~ ^[0-9+$] ]];then if [ $space -gt $warning ];then echo $disk:$space fi fi done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/check_disk.sh /dev/sda1:15 [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat shell/ddos.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/ddos.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** netstat -nta | sed -nr '/^tcp /s/.* ([1-9].*):.*/1/p' | sort| uniq -c | while read iplist;do linknum=`echo $iplist | cut -d " " -f 1` ip=`echo $iplist | cut -d " " -f 2` if [ $linknum -ge 2 ];then echo $ip >> /root/cracker_ip.log fi done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/ddos.sh [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat cracker_ip.log 172.30.1.254 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
六.请用while循环实现以下小练习
1>.计算1到100之间的和
[root@node101.yinzhengjie.org.cn ~]# cat shell/sum.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/sum.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** sum=0 read -t 30 -p "Please enter the start number>>> " StartNumber read -t 30 -p "Please enter an end number>>> " EndNumber while [ $StartNumber -le $EndNumber ] do sum=$(( $sum + $StartNumber )) StartNumber=$(( $StartNumber + 1 )) done StartNumber=$(( $StartNumber - $EndNumber )) echo "从$StartNumber加到$EndNumber的总和是:$sum" [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/sum.sh Please enter the start number>>> 1 Please enter an end number>>> 100 从1加到100的总和是:5050 [root@node101.yinzhengjie.org.cn ~]#
2>.若有人使用"yinzhengjie"用户登录则立即踢出它并将其IP拉入黑名单,以防止该用户继续使用该IP地址进行登录。
[root@node101.yinzhengjie.org.cn ~]# cat shell/scan_cracker.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/scan_cracker.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** while true;do #获取使用"yinzhengjie"用户登录的IP地址 iplist=`who | sed -nr '/^yinzhengjie/s/.*((.*))/1/p'` #判断当前使用有人使用"yinzhengjie"用户登录 if [ "$iplist" ];then #若使用"yinzhengjie"用户登录成功就直接剔除掉该用户 pkill -9 -U yinzhengjie echo "cracker is killed" #将刚刚使用"yinzhengjie"用户的IP地址加入黑名单,以防止该用户再次登录。 echo sshd:$iplist >> /etc/hosts.deny fi sleep 10 done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/scan_cracker.sh #运行该脚本后使用"yinzhengjie"用户登录测试,观察相关的配置文件及输出信息。 cracker is killed ^C [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat /etc/hosts.deny # # hosts.deny This file contains access rules which are used to # deny connections to network services that either use # the tcp_wrappers library or that have been # started through a tcp_wrappers-enabled xinetd. # # The rules in this file can also be set up in # /etc/hosts.allow with a 'deny' option instead. # # See 'man 5 hosts_options' and 'man 5 hosts_access' # for information on rule syntax. # See 'man tcpd' for information on tcp_wrappers # sshd:172.30.1.254 [root@node101.yinzhengjie.org.cn ~]#
3>.编写脚本,求100以内所有正奇数之和
4>.编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态,并统计在线和离线主机各多少
5>.编写脚本,打印九九乘法表
6>.编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大值和最小值
7>.编写脚本,实现打印国际象棋棋盘
8>.后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机执行命令: echo $RANDOM|md5sum|cut –c1-10 后的结果,请破解这些字符串对应的RANDOM值
9>.编写脚本,将最近登录失败的IP统计出来并保存在配置文件中
[root@node101.yinzhengjie.org.cn ~]# cat shell/check_lastb.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-25 #FileName: shell/check_lastb.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** localnet="172.30.1" sleeptime=10 while true;do #使用"lastb"命令来查看最近登录服务器失败的信息,并将非"$localnet"网段的IP过滤出来。 iplist=`lastb | grep -Eo "(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"|grep -v "$ localnet" |sort -u` #此处不要对"$iplist"加引号,因为加了引号后会把所有的IP地址当作一个整体来使用了,我们需要的是没有IP单独一行 for ip in $iplist;do #判断当前ip是否已经写入文件,若没有则写入,若能找到就短路或了. grep "$ip" /root/crack_iplist.log &> /dev/null || echo "$ip" >> /root/crack_iplist.log done sleep $sleeptime done [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#