1.语法结构:
(1)列表循环
(2)不带列表循环
(3)类C风格的for循环
格式:
for 变量名 in 取值列表
do
命令序列
done
2.用法:
读取不同的变量值,用来逐个执行同一组命令
for循环经常使用在已经知道要进行多少次循环的场景
例1:显示从0到9的数字
方法一:
#!/bin/bash
for i in {0..9}
do
echo $i
done
方法二:
#!/bin/bash
for i in $(seq 0 9)
do
echo $i
done
例2:打印五次hello world
#!/bin/bash
for i in {1..5}
do
echo hello world
done
例3:1到10 之间奇数和
#/bin/bash
sum=0
for i in {1..10..2}
do
sum=$[sum+i]
let i++
done
echo "10以内的奇数和为:$sum"
例4:输出0-50之间的偶数
[root@server ~]# vim for.sh
#!/bin/bash
for i in {0..50..2] ###..2代表步长为2,每隔2个
do
echo $i
done
附小技巧:花括号{}和seq在for循环的应用
for i in {1..50..2] 1-50的奇数
for i in {2..50..2) 1-50的偶数
for i in {10..1} 1-10倒序排列
for i in $(seq 10) 1-10正序排列
for i in $(seq 10 -1 1) 1-10倒序排列
for i in $(seq 1 2 10) 1-10的奇数,中间为步长
for i in s (seq 0 2 10) 1-10的偶数,中间为步长
不带列表循环执行时由用户指定参数和参数的个数决定的
格式:
for 变量名
do
command
done
例:打印hello world
[ root@server ~]# vim k.sh
#!/bin/ bash
for i
do
echo hello world
done
[root&server ~]# sh k.sh ###没有给脚本传参所以执行了没有结果
[ root@server ~-]# sh k.sh a ###把a赋值给变量i,i有值了它就开始执行do ..done了
hello world
第二种:
for i
do
echo $i
done
[root@localhost ~]# sh k.sh helloworld
helloworld
类c风格的for循环
for ( (expr1;expr2;expr3))
do
command
done
expr1:定义变量并赋初值
expr2:决定是否循环
expr3:决定循环变量如何改变,决定循环什么时候退出
例:打印 1-5 迭代
#!/bin/bash
for ((i=1;i<=5;i++) )do
echo $i
done
注:
i++ : i=1+1 先赋值再运算 i=1 之后再 +1
++i : 1+1=i 先运算再赋值 1+1 之后再 =i
例2:打印1-10的奇数
#! /bin/bash
for ( (i=1 ;i<=10;i+=2)) ###i=i+2
do
echo $i
done
附:类c风格运算符用法
++ 自身变量+1
– 自身变量-1
+=5 自身变量+5
-=5 自身变量-5
=5 自身变量5
/=5 自身变量/5
%=5 自身变量%5
例3:计算1-100的奇数和
#!/bin/bash
sum=0
for ( (i=1 ;i<=100 ;i+=2) )
do
let sum=$i+$sum
done
echo "1-100的奇数和为:$sum"
其他案例:
例1:批量添加用户两种方式
1)以后缀批量变化添加
for i in {1..5}
do
useradd stu$i
echo "123" | passwd --stdin stu$i
done
2)脚本批量添加用户
#!/bin/bash
ULIST=$ (cat /root/users.txt)
for UNAME in $ULIST
do
useradd $UNAME
echo "123456" | passwd --stdin $UNAME &>/dev/null
done
批量删除用户的脚本
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
userdel -r $UNAME &>/ dev/ null
done
例2、根据IP地址列表检查主机状态
-c发送包的数量
-i发送ping包间隔
-W超时时间
1)根据文本查看
#!/bin/bash
HLIST=$ (cat /root/ipadds.txt)
for IP in $HLIST
do
ping -c 3 -i 0.2 -W 3 $IP &> /dev/null
if [ $? -eq 0 ];then
echo "Host $IP is up."
else
echo "Host $IP is down . "
fi
done
2)根据段查看
#!/bin/bash
network="192.168.10"
for addr in { 1..254 }
do
ping -c 2 -i 0.5 -w 3 $network.$addr &> /dev/null
if [ $? -eq 0 ] ;then
echo " $network. $addr is up"
else
echo "$network.$addr is down"
fi
done
用户输入密码,脚本判断密码是否正确,输入正确提示正确信息,连续输错3次则报警
#!/bin/bash
init=123456
for i in {1. .3}
do
read -p "请输入密码:" pass
if [ $pass == $init ] ; then
echo “密码正确"
exit
fi
done
echo“警告:密码错误"
while循环一般用于有条件判断的循环,若判断条件为真,则进入循环,当条件为假就跳出循环
用法:
重复测试某个条件,只要条件成立则反复执行
常在不知道范围的时候成立
格式:
while 条件测试操作
do
命令序列
done
#!/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
while死循环
while [ 1 -eq 1 ] //写一个永远为真的表达式,1等于1这个条件永远为真,所以这个脚本会一直循环下去
do
command
done
while true
do
command
done
while :
do
command
done
例:猜数字小游戏
#!/bin/bash
pc_num=$[RANDOM%3+1]
count=0
while true
do
read -p "请输入一个数字:" user_num
if [ $user_num -eq $pc_num ]
then
echo "答对啦"
break
elif [ $user_num -gt $pc_num ]
then
echo "你的数字太大了"
else
echo "你的数字太小了"
fi
let count++
done
echo 你输入的次数为:$count
例2:猜商品价格游戏
$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次!"
例3:实时监控本机内存和硬盘剩余空间,剩余内存小于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 <
跟while相反,条件为假进入循环,条件为真退出循环
用法: 重复测试某个条件,只要条件不成立则反复执行
格式:
until 条件测试操作
do
命令序列
done
#!/bin/bash
sum=0
i=0
until [ $i -gt 100 ]
do
sum=$[sum+i]
let i++
done
echo "{1..100}的和:$sum"
死循环结构
until false
do
command
done
until [ 1 -ne 1 ]
do
command
done
案例:登录 zhangsan 用户 使用 root 发消息给zhangsan
#!/bin/bash
username=$1
#判断信息格式
if [ $# -lt 1 ];then
echo "Usage:`basename $0` []"
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-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
打断,马上停止本次循环,执行循环体外的代码
例: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 $i
直接跳出程序所以不会执行最后的echo hi,并且返回码是100通过$?查看
1.for语句的结构
2.while语句的结构
3.until语句的结构
4.循环控制语句