shell编程之for、while、until循环语句
一、循环概述
循环:在一定条件下(为了避免陷入死循环),重复执行的命令或代码
循环的作用:节约了大量的时间,也提高了脚本的复用率
遍历:对一组数据结构中的每一个元素进行一次访问的过程、进行操作或者输出
- 循环是一种控制流程的结构,用于重复执行代码
- 遍历是访问,访问数据
- 在绝大多数情况下,循环和遍历结合使用
二、for单层循环
2.1 常规格式
for 变量名 in 取值列表 do 命令序列 done
2.1.1 批量添加用户
- 用户名存放在users.txt文件中,每行一个
- 初始密码均设为123456
- 验证脚本
[root@localhost opt]# vim users.txt aa bb cc dd
[root@localhost opt]# vim useradd.sh for i in $(cat /opt/users.txt) do useradd $i echo 123456 | passwd --stdin $i done
[root@localhost opt]# sh useradd.sh //运行代码 更改用户 aa 的密码 。 passwd:所有的身份验证令牌已经成功更新。 更改用户 bb 的密码 。 passwd:所有的身份验证令牌已经成功更新。 更改用户 cc 的密码 。 passwd:所有的身份验证令牌已经成功更新。 更改用户 dd 的密码 。 passwd:所有的身份验证令牌已经成功更新。 [root@localhost opt]# cat /etc/passwd //验证
2.2 类C语言格式
for ((变量初始值; 变量范围; 迭代方法)) do 命令序列 done for((;;)) //死循环的写法
2.2.1 计算1~100所有整数的和
[root@localhost opt]# vim for2.sh sum=0 for ((i=1;i<=100;i++)) do sum=$[$i+$sum] done echo $sum
[root@localhost opt]# sh for2.sh 5050
2.3 步长格式
for i in `seq 数1 数2 数3` //数1表示从哪里开始; 数2表示每次加(减)几; 数3表示加(减)到几为止; do 命令序列 done
三、多线程执行脚本(并行执行)
普通for循环是串行,一个一个执行。
在do和done中间增加 { } 符号,可以多线程同时执行
在{}后加上& 符号,表示将进程放到后台运行
- 案例:
检测指定范围主机是否通信,并将通信的主机ip输出到文件host_ip中
[root@localhost opt]# vim for10.sh for ((i=1;i<=254;i++)) do { ping -c 3 -w 2 192.168.147.$i &> /dev/null if [ $? -eq 0 ] then echo "192.168.147.$i" >> /opt/host_ip fi }& #{ }表示多线程同时执行 #增加 & 符号,表示将进程放到后台运行 done
四、补充
4.1 echo的常用选项
选项 含义 echo -n 表示不换行输出 echo -e 输出转义字符,将转义后的内容输出到屏幕上
4.2 常用转义字符
echo -ne 只有加了-e才能执行下面的转义符:
五、双重for循环
双重循环需要具备的前提——存在两个以上的自变量
- 演示:倒直角三角形
[root@localhost opt]# vim doubfor1.sh for ((i=9;i>=1;i--)) do for ((j=1;j<=i;j++)) do echo -n "*" done echo done
六、结束循环
6.1 break
执行break之后直接跳出当前循环,但循环外的语句仍然会执行
- 示例
[root@localhost opt]# vim break1.sh for i in {1..3} do for j in {1..5} do #当内层循环到达第三次时,break跳出内层循环 if [ $j -eq 3 ] then break fi echo $j done done
break 1 为跳出单层循环,默认为break;后面的数字为跳出层数。例如"break 2"为跳出2层循环
- 示例
[root@localhost opt]# vim break1.sh for i in {1..3} do for j in {1..5} do if [ $j -eq 3 ] then break 2 fi echo $j done done
6.2 continue
满足条件时跳出当前循环,但不影响后续循环的执行,它的作用是在循环内部跳过本次循环并继续下一次循环
- 示例
[root@localhost opt]# vim continue1.sh for i in {1..5} do for j in {1..5} do if [ $j -eq 3 ] then continue fi echo $j done done
continue2:内循环和外循环在达到条件时都跳出循环
- 示例
[root@localhost opt]# vim continue1.sh for i in {1..5} do for j in {1..5} do if [ $j -eq 3 ] then continue 2 fi echo $j don done
七、生成随机数
$RANDOM //0~32767 $(($RANDOM%100)) //0~99 $(($RANDOM%100+1)) //1~100 $(($RANDOM%1000+1)) //1~1000
- 示例:猜数字,猜中才能退出
[root@localhost opt]# vim caishuzi.sh con=0 a=$(($RANDOM%100+1)) for ((;;)) do let con++ read -p "请输入一个数:" num if [[ $num -eq a ]] then echo "你猜对了,一共猜了${con}次" break elif [[ $num -gt a ]] then echo "你猜大了,请重新输入" else [[ $num -lt a ]] echo "你猜小了,请重新输入" fi done
八、while
重复测试某个条件,只要条件成立则反复执行
格式:
while 条件测试操作 do 命令序列 done
- 示例:用while实现1~10求和
[root@localhost opt]# vim while1.sh i=0 sum=0 while [ $i -lt 10 ] do let i++ sum=$(($sum+$i)) done echo $sum
while的死循环写法: while true while [ 1 -eq 1 ]
九、until
重复测试某个条件,只要条件不成立则反复执行
格式:
until 条件测试操作 do 命令序列 done
- 示例:until实现1~100求和
[root@localhost opt]# vim until1.sh i=0 sum=0 until [ $i -gt 100 ] do sum=$(($sum+$i)) let i++ done echo $sum