Shell脚本——循环语句【for、while、until】

171 阅读4分钟

一、 echo 命令

echo 用在脚本里修饰格式

命令格式:

`echo -n`   表示不换行输出
`echo -e`   表示输出转义符
转义符作用
\r光标移至行首,并且不换行
\s当前shell的名称,如bash
\t插入Tab键,制表符
\n输出换行
\f换行,但光标仍停留在原处
\表示插入""本身转义
\b表示退格 不显示前一个字符
\c抑制更多的输出或不换行

二、 循环概述

循环含义:将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件。

重复运行次数:

  • 循环次数事先已知 ( for 已知次数情况下 )
  • 循环次数事先未知 ( while 和 until 是已知条件)

常见的循环的命令:for, while, until

三、 for循环语句

1. 列表循环

语句格式:

for  变量名  in   前面变量的取值列表    //变量的名字前不用加$
do
命令序列
done
例:
#!/bin/bash
for i in a b c d
//i的取值是第一次为1第二次为2 第三次 为3 第四次为4第五次为5
do
//要循环的事件
echo "hello world"
//循环几次 由上面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的奇数,中间为步长

2. 类似于C语言风格的for循环

语句格式:

for ((expr1;expr2;expr3))
do
     command
done

expr1:定义变量并赋初值
expr2:决定是否循环
expr3:决定循环变量如何改变,决定循环什么时候退出
例:求1-100的和 (不知次数,设置退出循环条件)
[root@node1 ~]#  vim qiuhe.sh   //编写脚本
#!/bin/bash

sum=0
for  ((i=0 ;i<=100 ; i++ ))
do
let sum+=i
done
echo $sum

[root@node1 ~]#  bash qiuhe.sh  //执行脚本
5050

示例

1. 累加求和

1-100的和
[root@node1 ~]#  vim qh.sh  //编写脚本

#!/bin/bash# 

sum=0
for i in {1..100}
do
sum=$[i+sum]
done
echo $sum

[root@node1 ~]#  sh qh.sh   //执行脚本
5050

i1=1  sum1=0   sum2=i1+sum1=1
i2=2  sum2=1   sum3=i2+sum2=3
i3=3  sum3=3   sum4=i3+sum3=6
i4=4  sum4=6   sum5=i4+sum4=10
......

2. 修改文件名

给/data下的所有文件添加后缀.bak
[root@node1 data]#  touch  {1..10}.txt
[root@node1 data]#  ls
10.txt  1.txt  2.txt  3.txt  4.txt  5.txt  6.txt  7.txt  8.txt  9.txt
[root@node1 data]#  vim gm.sh  //编写脚本

#!/bin/bash

for i in *      //变量i的取值范围是 当前文件夹下的所有文件      
do
mv $i  ${i}.bak
done

[root@node1 data]#  bash gm.sh   //执行脚本
[root@node1 data]#  ls
10.txt.bak  1.txt.bak  2.txt.bak  3.txt.bak  4.txt.bak  5.txt.bak  6.txt.bak  7.txt.bak  8.txt.bak  9.txt.bak  gm.sh.bak

3. 批量添加用户

用户名存放在name.txt文件中,每行一个
初始密码均设为123456
[root@node1 data]#  cat name.txt
xue
li
xue
wen
xuan
[root@node1 data]#  vim name.sh  //编写脚本

#!/bin/bash
for i in `cat /data/name.txt`
do
if id $i;then
echo "用户己存在"
else
useradd $i
   if [ $? -eq 0 ];then
   echo "用户$i 建立成功"
   echo 123456 | passwd --stdin $i
   else
   echo "建立用户fail"
   fi
fi
done

[root@node1 data]#  bash name.sh    //执行脚本
id: xue: no such user
用户xue 建立成功
更改用户 xue 的密码 。
passwd:所有的身份验证令牌已经成功更新。
id: li: no such user
用户li 建立成功
更改用户 li 的密码 。
passwd:所有的身份验证令牌已经成功更新。
uid=1004(xue) gid=1004(xue) 组=1004(xue)
用户己存在
id: wen: no such user
用户wen 建立成功
更改用户 wen 的密码 。
passwd:所有的身份验证令牌已经成功更新。
id: xuan: no such user
用户xuan 建立成功
更改用户 xuan 的密码 。
passwd:所有的身份验证令牌已经成功更新。

4. 九九乘法表(双重循环)

  1. 先打印一行*
[root@node1 data]#  vim cfb.sh  //编写脚本 

#!/bin/bash
for i  in {1..9}
do
echo -e "*\c"   //不换行打印*
done

[root@node1 data]#  bash cfb.sh   //执行脚本
*********[root@node1 data]#
  1. 打印正方形
[root@node1 data]#  vim cfb.sh  //编写脚本

#!/bin/bash
for j in {1..9}
do
  for i  in {1..9}
  do
  echo -e "*\c"   //不换行,一行打印9个*
  done
echo  //换行,打印9行
done

[root@node1 data]#  bash cfb.sh 
*********
*********
*********
*********
*********
*********
*********
*********
*********
  1. 打印直角三角形
[root@node1 data]#  vim cfb.sh  //编写脚本

#!/bin/bash
for j in {1..9}
do
  for i  in `seq $j`   //注意不要写{1..$j}!bash只能执行一次,这样写会不识别
  do
  echo -e "*\c"  //不换行,一行打印9个*
  done
echo  //换行,打印9行
done

[root@node1 data]#  bash cfb.sh   //执行脚本
*
**
***
****
*****
******
*******
********
*********
  1. 带入数字
[root@node1 data]#  vim cfb.sh   //编写脚本

#!/bin/bash
for j in {1..9}
do
  for i  in `seq $j`
  do
  echo -e "${i}*${j} \c"   //加个空格更美观
  done
echo
done

[root@node1 data]#  bash cfb.sh   //执行脚本
1*1 
1*2 2*2 
1*3 2*3 3*3 
1*4 2*4 3*4 4*4 
1*5 2*5 3*5 4*5 5*5 
1*6 2*6 3*6 4*6 5*6 6*6 
1*7 2*7 3*7 4*7 5*7 6*7 7*7 
1*8 2*8 3*8 4*8 5*8 6*8 7*8 8*8 
1*9 2*9 3*9 4*9 5*9 6*9 7*9 8*9 9*9 
  1. 计算结果
[root@node1 data]#  vim cfb.sh  //编写脚本

#!/bin/bash
for j in {1..9}
do
  for i  in `seq $j`
  do
  echo -e "${i}*${j}=$[i*j] \t\c"   //制表符\t对齐
  done
echo
done

[root@node1 data]#  bash cfb.sh    //执行脚本
1*1=1 	
1*2=2 	2*2=4 	
1*3=3 	2*3=6 	3*3=9 	
1*4=4 	2*4=8 	3*4=12 	4*4=16 	
1*5=5 	2*5=10 	3*5=15 	4*5=20 	5*5=25 	
1*6=6 	2*6=12 	3*6=18 	4*6=24 	5*6=30 	6*6=36 	
1*7=7 	2*7=14 	3*7=21 	4*7=28 	5*7=35 	6*7=42 	7*7=49 	
1*8=8 	2*8=16 	3*8=24 	4*8=32 	5*8=40 	6*8=48 	7*8=56 	8*8=64 	
1*9=9 	2*9=18 	3*9=27 	4*9=36 	5*9=45 	6*9=54 	7*9=63 	8*9=72 	9*9=81

四、 while语句

while循环一般用于有条件判断的循环,若判断条件为真,则进入循环,当条件为假就跳出循环。

语句格式:

while  条件测试操作
do   
   命令序列
done


例:
while  未猜中正确价格
do   
   反复猜测商品价格
done

重复测试某个条件,只要条件成立则反复执行

示例

1. 求和

1-100的和
[root@node1 data]#  vim wqh.sh  //编写脚本

#!/bin/bash
i=0
sum=0
while [ $i -le 100 ]
do
sum=$[i+sum]
let i++
done
echo $sum

[root@node1 data]#  bash wqh.sh   //执行脚本
5050

i=0   sum=0    sum1=0+0    i=0+1
i=1   sum1=0   sum2=1+0    i=1+1
i=2   sum2=1   sum3=2+1    i=2+1
i=3   sum3=3   sum4=3+3    i=3+1
i=4   sum4=6   sum5=4+6    i=4+1

2. 批量添加用户

用户名称以stu开头,按数字顺序进行编号
一共添加20个用户,即stu1、stu2、… 、stu20
初始密码均设为123456

[root@node1 data]#  vim 123.sh   //编写脚本

#!/bin/bash
i=1
while [ $i -le 20 ]
do
useradd stu$i
echo 123456 | passwd --stdin stu$i
let i++
done

[root@node1 data]#  bash 123.sh   //执行脚本
while用户脚本.png

3. 猜商品价格游戏

通过变量RANDOM获得随机数
提示用户猜测并记录次数,猜中后退出循环

[root@node1 data]#  vim jg.sh   //编写脚本

#!/bin/bash
p=`echo $[RANDOM%1000+1]`
t=0

while true
do
read -p "请输入商品的价格1-1000:" num
let t++
if [ $num -eq $p ]
then
echo "恭喜你猜中了,实际价格是$p"
echo "您一共猜了${t}次"
exit 0
elif [ $num -gt $p ]
then
echo "您猜的价格高了" 
else
echo "您猜的价格低了"
fi
done

[root@node1 data]#  bash jg.sh  //执行脚本
while猜价格.png

五、 until语句

重复测试某个条件,只要条件不成立则反复执行

语句格式:

until  条件测试操作
do
  命令序列
done

六、 跳出循环

  • break跳出单个循环 break 数字 数字是几代表跳出n层循环
  • continue终止某次循环中的命令,但是不会完全终止命令
  • exit 直接退出脚本