循环
一、for循环
语法格式:
for 变量名 in 取值列表
do
命令
done
案例
for循环执行次数,取决于取值列表中的变量个数
#!/bin/bash
for a in `seq 5` #输出1-5
do
echo $a
done
----------or---------
for a in {1..5}
----------or---------
for((i=1;i<=5;i++));do echo $i;done
使用ii(())双括号,可以支持C语言的一些命令
i=1;i<=5;i++ #i初始值为1,如果i小于等于5时执行循环,每次循环后+1
实用for 循环遍历 当前目录
for i in `ls`
do
echo $i
done
删除当前目录下的5.6.7.8文档
#!/bin/bash
a=`find . -type f -name "[1-9]"`
for i in $a
do
rm -rf $i
done
写一个shell ,随机点名
#!/bin/bash
#grep -w 只显示全字符合的列
num=$[RANDOM%25+1]
echo "$num"
a=`cat ./name | grep -w "$num" | awk '{print $2}'`
echo "今天回答的人是$a"
输出1-10 的奇数
例子:
#!/bin/bash
for((i=1;i<=10;i+=2)) #类C的for表达
do
echo $i
done
-------------or--------------
for a in {1..10..2} #步长为2
do
echo $a
done
-------------or--------------
for b in `seq 1 2 10` #步长为2,以1为起始,奇数
do
echo $b
done
tip:
++i:先运算后赋值
i++:先赋值后运算
附2:类C风格运算符用法
++自身变量+1
--自身变量-1
+=5自身变量+5
-=5自身变量-5
*=5自身变量*5
/=5自身变量/5
%=5自身变量%5
求奇数和
#!/bin/bash
sum=0
for((i=1;i<=100;i+=2))
do
let sum=$i+$sum
done
echo "1-100的奇数和为:$sum"
求偶数和
#!/bin/bash
for((i=0;i<=20;i+=2))
do
sum=$[$sum+$i]
done
echo "1-20的偶数和为:$sum"
求偶数和和一个随机数之和
#!/bin/bash
rand=$[RANDOM%50+1]
for((i=0;i<=$rand;i+=2))
do
sum=$[$sum+$i]
done
sum_1=$[$rand+$sum]
echo "1-20的偶数和为:$sum_1"
小结:
小结:for循环中for i in {list} 使用方式
i为自定义变量名,
in 首先将in之 后的内容,定义为一个list然后循环对列表中的元素进行取值,并每次取值后赋予给变量i(变量名)
{list}列表:①定义循环次数@每个元素,在每次循环时都会被依次取出,然后复制给变量名
以do为分割
然后 command:定义每次循环时,要输出的指令
done结束
二、for循环脚本
检测指定范围主机是否通信,并将通信的主机ip输出到文件/opt/host_ip中
#!/bin/bash
## ping -c 回应次数 -i 间隔时间 -w超时时间
for i in 192.168.100.{1,10,20}
do
ping -c 3 -i 0.2 -w 3 $i &>/dev/null
if [ $? -eq 0 ];then
echo "$i is up"
else echo "$i is down"
fi
done
用户输入密码,脚本判断密码是否正确,输入正确提示正确信息,连续输错3次则报警
#!/bin/bash
passwd=123456
for i in {1..3}
do
read -p "请输入6位密码:" key
if [ $passwd -eq $key ]
then
echo "密码正确"
exit 0
else
echo "你输错了"
fi
done
echo "您已经输错三次,告警"
遍历,执行花名册
#!/bin/bash
#grep -w 只显示全字符合的列
num=$[RANDOM%25+1]
echo "$num"
a=`cat ./name | grep -w "$num" | awk '{print $2}'`
echo "今天回答的人是$a"
------------or-------------
for i in $num
do
echo "今天回答问题的人是 $a"
done
编写能够自动生成一个8位随机密码的脚本
99乘法表
#!/bin/bash
#99乘法表
i=1
while [ $i -le 9 ]
do
j=1
while [ $j -le $i ]
do
echo -e -n "$j*$i=$[$i*$j] \t"
let j++
done
let i++
echo " "
done
数字炸弹游戏Ⅱ: 要求在1-10内定义一个数字,在11-20内定义一个数字,然后与player交互两次,1:请输入1-10内的一个数字: ,如果在3次外猜中,游戏通关1/2 否则游戏失败, 1/2关通过后,交互: 2:请输入11-20内的一个数字,如果3次外猜中,则游戏通关,否则,游戏失败 ,最后输出一共猜了几次
#!/bin/bash
num=$[RANDOM%10+1]
num2=$[RANDOM%10+11]
timea=0
timeb=1
while true
do
read -p "输入您猜的数字,游戏1:范围(1-10):" num_1
#echo "答案$num" #测试
timea=$[$timea+1]
if [ $num -eq $num_1 ]
then
if [ $timea -le 3 ]
then echo "你踩到炸弹了,gg"
break
else echo "游戏通关1/2"
break
fi
break
elif [ $num -gt $num_1 ]
then
echo "你猜小了,共猜错"$timea"次"
else
echo "你猜大了,共猜错"$timea"次"
fi
done
while [ $timea -ge 4 ]
do
read -p "恭喜你逃脱成功,游戏2:范围(11-20):" num_2
#echo "答案$num2" #测试
if [ $num2 -eq $num_2 ]
then
if [ $timeb -lt 3 ]
then echo "哎,又踩到炸弹了,倒霉蛋"
break
else echo "你已经通关,用了"$timea"次逃脱"
break
fi
break
elif [ $num2 -gt $num_2 ]
then echo "你猜小了,共猜错"$timeb"次"
else echo "你猜大了,共猜错"$timeb"次"
fi
timea=$[$timea+1]
timeb=$[$timeb+1]
done
#现在有个抽奖箱,里面放了3位数字,每次取一个数字,查看对应id的人名 ,然后记录次数+1,并且取完之后,将数字丢回抽奖
箱,再次进行抽取,再次记录id对应的人名,并记录次数+1 ,反复10次,最后统计谁的次数最多,谁就为幸运用户
人名 3个
#!/bin/bash
num1=0
num2=0
num3=0
echo "这里有个抽奖箱"
echo "里面有三个球"
echo "美羊羊"
echo "喜羊羊"
echo "懒洋洋"
while true
do
y=$i
read -p "你想抽几次" i
echo "正在抽球,请稍后……"
sleep 1
for((a=1;a<=$i;a++))
do
text=$[$RANDOM%3+1]
case $text in
1)
#echo "美羊羊"
num1=$[$num1+1]
#echo $num1
;;
2)
#echo "喜羊羊"
num2=$[$num2+1]
#echo $num2
;;
3)
#echo "懒羊羊"
num3=$[$num3+1]
#echo $num3
;;
*)
;;
esac
done
echo "美羊羊抽中"$num1"次"
echo "喜羊羊抽中"$num2"次"
echo "懒羊羊抽中"$num3"次"
if [ $num3 -gt $num2 -a $num3 -gt $num1 ]
then echo "懒洋洋是幸运观众,抽中了"$num3"次"
break
elif [ $num2 -gt $num1 -a $num2 -gt $num3 ]
then echo "喜羊羊是幸运观众,抽中了"$num2"次"
break
elif [ $num1 -gt $num2 -a $num1 -gt $num3 ]
then echo "美羊羊是幸运观众,抽中"$num1"次"
else [ $num1 -eq $num2 -o $num2 -eq $num3 -o $num3 -eq $num1 ]
read -p "平局,重新抽取,按y确认" y
fi
done
~
~
~
三、while循环
1、语法结构
2、死循环
(1)语法结构(3种)
while循环一般用于有条件判断的循环,若判断条件为真,则进入循环,当条件为假就跳出循环
1、语法结构
while 表达式
do
command
done
例1:打印1-5
#!/bin/bash
i=1
while [ $i -le 5 ]
do
echo $i
let i++ //注意这里如果不改变$i的值,会变成死循环
i=$[$i+1] //两种写法
done
echo "最后i的值为: $i"
例2:输出1-100之间不能被3整除的数字
#!/bin/bash
i=1
while [ $i -le 100 ]
do
if [[ $i%3 -ne 0 ]]
then echo "$i"
fi
let i++
done
例3:打印1-100的和
#!/bin/bash
i=1
sum=0
while [ $i -le 100 ]
do
let sum=$i+$sum
let i++
done
echo $sum
例4:监控某服务(httpd)运行状态
while ps aux | grep httpd | grep -v grep &> /dev/null
do
echo "httpd 正在运行中"
sleep 2
done
echo "httpd 不在运行"
2、while死循环
while [ 1 -eq 1 ] //写一个永远为真的表达式,1等于1这个条件永远为真,所以这个脚本会一直循环下去
while true
do
command
done
while :
do
command
done
例1:猜数字,猜不对就一直猜
num=10
while true
do
read -p "请输入数字:" shu
if [ $shu -eq $num ];then
echo "你猜对了"
break
elif [ $shu -gt $num ];then
echo "你猜大了"
elif [ $shu -lt $num ];then
echo "你猜小了"
fi
done
例2、批量添加规律编号的用户
#!/bin/bash
USERS="stu"
i=1
while [ $i -le 20 ]
do
useradd ${USERS}$i
echo "123456" | passwd --stdin ${USERS}$i &> /dev/null
let i++
done
例3、猜商品价格游戏
$random用于生成0—32767的随机数
第一种方法
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
a=0
echo "商品实际价格范围为 0-999,猜猜看是多少?"
while true
do
read -p "请输入你猜测的价格数目:" n
let a++
if [ $n -eq $PRICE ] ; then
echo "恭喜你答对了,实际价格是 $PRICE"
echo "你总共猜测了 $a 次"
exit 0
elif [ $n -gt $PRICE ] ; then
echo "你猜高了!"
else
echo "你猜低了!"
fi
done
第二种方法
#!/bin/bash
sorce=$[$RANDOM % 1000]
a=1
num=0
while[ $a -lt 2 ]
do
read -p "请输入你猜的价格(1-999之 间) :" price
if [ $price -eq $sorce ] ; then
echo "恭喜你猜对了!"
let num++
let a++
elif [ $price -gt $sorce ] ; then
echo "你猜高了!"
let num++
elif[ $price -lt $sorce ] ; then
echo "你猜小了!"
let num++
fi
done
echo "你一共猜了$num次!"
例4 实时监控本机内存和硬盘剩余空间
剩余内存小于500M、根分区剩余空间小于1000M 时,发送报警邮件给 root 管理员
#!/bin/bash
#提取根分区剩余空间
disk_size=$(df / |awk '/\//{print $4}')
#提取内存剩余空间
mem_size=$(free |awk '/Mem/{print $4}')
while :
do
#注意内存和磁盘提取的空间大小都是以Kb 为单位
if [ $disk_size ‐le 512000 -a $mem_size ‐le 1024000 ];then
mail ‐s Warning root <<EOF
Insufficient resources,资源不足EOF
fi
done
例5 定义网卡流量
#!/bin/bash
#定义流量单位
DW=kb/s
while :
do
#定义某一时间点的提取网卡流量数值,我这里的网卡是ens33
OLD_IN=$(cat /proc/net/dev | awk '$1~/ens33/{print $2}')
OLD_OUT=`cat /proc/net/dev | awk '$1~/ens33/{print $10}'`
sleep 5
#定义下一个时间点的提取网卡流量数值。
NEW_IN=$(cat /proc/net/dev | awk '$1~/ens33/{print $2}')
NEW_OUT=`cat /proc/net/dev | awk '$1~/ens33/{print $10}'`
#进行流量的计算,默认是Bytes,转换成kb/s
IN=$[$[$NEW_IN - $OLD_IN]/1024]$DW
OUT=$[$[$NEW_OUT - $OLD_OUT]/1024]$DW
sleep 5
#打印对应的值
echo -e "接收数据:${IN}\t发送数据:$OUT"
例6、商店购物
#!/bin/bash
#需求1:首先要求有4家店,每家店 3个商品(3个商品的价格统一为100 200 300),然后要求以交互式的方式,让用户选择进入
哪家店,并且选择哪个商品
#需求2:用户可以循环进入门店,除非用户选择“退出”
sum=0
i=0
while [ $i -le 3 ]
do
let i++
echo "正在进入第"$i"家店"
read -p "是否进入(y/n):" choose
while [ $choose = "y" ]
do
echo "里面有3个商品 商品1:价格100 商品2:价格200 商品3:价格300"
read -p "请选择你要挑选的商品(1/2/3)" choose1
case $choose1 in
1)
echo "商品1购买成功"
sum=$[$sum+100] &>/dev/null
;;
2)
echo "商品2购买成功"
sum=$[$sum+200] &>/dev/null
;;
3)
echo "商品3购买成功"
sum=$[$sum+100] &>/dev/null
esac
read -p "是否继续在这里购物(y/n)" choose
done
if [ $choose = "n" ];then
continue
fi
done
echo "购物总价:$sum ,请支付"
~
3、until循环
跟while相反,条件为假进入循环,条件为真退出循环
语法结构
until 表达式
do
command
done
例1:计算1-50的和1275两种写法第一种
#!/bin/bash
i=0;s=0
until [ $i -eq 51 ]
do
let s+=i #s+=i,等价于s=s+i,使用加赋值
let i++
done
echo $s
第二种
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ] //这里注意如果是50的话条件为真循环结束它计算的是1-49的和,until [ $i -gt 50 ]也行
do
sum=$[$i+$sum]
let i++
done
echo "$sum"
死循环结构
until false
do
command
done
until [ 1 -ne 1 ]
do
command
done
案例2、登录zhangsan用户 使用root 发消息个zhangsan
#!/bin/bash
username=$1
#判断信息格式
if [ $# -lt 1 ];then
echo "Usage:`basename $0` <username> [<message>]"
exit 1
fi
#判断用户是否存在
if grep "^$username:" /etc/passwd >/dev/null ;then :
else
echo "用户不存在"
exit 1
fi
#用户是否在线,如果不在线每5秒联系一次
until who|grep "$username" >/dev/null
do
echo "用户不存在"
sleep 5
done
mes=$*
echo $mes | write $username
注:测试时切换下用户
四、循环控制语句
for循环一般会搭配条件判断语句和流程控制语句一起执行,那么就会出现需要跳过循环和中止循环的情况,控制循环的命令有以下3个
1、continue
继续,但不会执行循环体内下面的代码了,开始重新开始下一次循环
例1:打印1-5的数字,3不打印
#!/bin/bash
for ((i=1;i<=5;i++))
do
if [ $i -eq 3 ];then
continue
else
echo $i
fi
done
结果是1245,3不输出,因为跳出后面的echo语句执行下一次循环了
2、break
打断,马上停止本次循环,执行循环体外的代码
例2:1-10的数字,7后面的都不打印
#!/bin/bash
for ((i=1;i<=10;i++))
do
if [ $i -eq 8 ];then
break
else
echo $i
fi
done
3、exit
直接跳出程序,后面可跟状态返回码如exit 1等等
for i in {1..5}
do
if [ $i -eq 3 ];then
exit 100
else
echo $i
fi
done
echo hi
直接跳出程序所以不会执行最后的echo hi,并且返回码是100通过$?查看
echo $mes | write $username
注:测试时切换下用户
## 四、循环控制语句
for循环一般会搭配条件判断语句和流程控制语句一起执行,那么就会出现需要跳过循环和中止循环的情况,控制循环的命令有以下3个
### 1、continue
继续,但不会执行循环体内下面的代码了,开始重新开始下一次循环
例1:打印1-5的数字,3不打印
```bash
#!/bin/bash
for ((i=1;i<=5;i++))
do
if [ $i -eq 3 ];then
continue
else
echo $i
fi
done
结果是1245,3不输出,因为跳出后面的echo语句执行下一次循环了
2、break
打断,马上停止本次循环,执行循环体外的代码
例2:1-10的数字,7后面的都不打印
#!/bin/bash
for ((i=1;i<=10;i++))
do
if [ $i -eq 8 ];then
break
else
echo $i
fi
done
3、exit
直接跳出程序,后面可跟状态返回码如exit 1等等
for i in {1..5}
do
if [ $i -eq 3 ];then
exit 100
else
echo $i
fi
done
echo hi
直接跳出程序所以不会执行最后的echo hi,并且返回码是100通过$?查看