Shell脚本之循环语句

循环语句

for循环

  • 用于已知循环次数的场景。
  • 通过读取不同的变量值,用来逐个执行同一组命令。

基本格式

for 变量名称(注意是名称不是变量$等) [ in 名称范围 ] (可以不写)

do

执行内容 若满足循环则做什么动作

done for循环结束标志

for语句的结构

实例1

批量添加用户。用户名存放在users.txt文件中,每行一个,初始密码均设为123456,最后验证脚本。

复制代码
vim users.txt #输入要创建的用户名
复制代码
#/bin/bash
for i in $( cat users.txt )
do
   useradd  $i
   echo 123456 | passwd --stdin $i
done

禁用当前系统除了root用户以外的可登录用户

复制代码
#!/bin/bash
#禁用当前系统除了root用户以外的可登录用户

usrname=$(cat /etc/passwd | grep "/bin/bash$" | grep -v "^root" | awk -F: '{print $1}')

for iname in $usrname
do
   #echo $iname
   usermod -L $iname
done

实例2

根据IP地址检查主机状态。IP地址存放在ipadds.txt文件中,每行一个,使用ping命令检测各主机的连通性。

复制代码
#!bin/bash
for i in {100..115}
do
    ping -c 3 -i 0.5 -w 3 192.168.80.$i &> /dev/null
   if [[ $? -eq 0 ]]
   then
     echo "192.168.80.$i online"
   else
     echo "192.168.80.$i offline"
   fi
done

嵌套循环

复制代码
#!bin/bash
for i in {1..3}
do
  for j in {1..5}
   do
     if [ $j -eq 3 ]
     then
     break
     fi
     echo $j
     done
done

while语句的结构

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

while语句应用示例1:批量添加用户

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

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

while语句应用示例2:猜商品价格游戏

猜商品价格游戏。通过变量RANDOM获得随机数,提示用户猜测并记录次数,猜中后退出循环。

复制代码
#!bin/bash
num=`echo $[ RANDOM%100+1 ]`
time=0
while true
 do
read -p "请用户猜一个数字(1-100):" a
  let time++
  if [ $a -eq $num ]
  then
    echo "恭喜你猜对了,$num"
    echo "你一共猜了${time}次"
   break
  elif [ $a -lt $num ]
   then
      echo "你猜小了,往大了猜"
    elif [ $a -gt $num ]
    then
      echo "你猜大了,往小了猜"
  fi
done

while语句应用示例3:计算从1到100所有整数的和

复制代码
#!bin/bash
#计算从1到100所有整数的和
a=1
sum=0
while  [ $a -le 100 ]
do
    let sum+=a
    let a++
done

echo "1到100总和为$sum"

while语句应用示例3:提示用户输入一个小于100的整数,并计算从1到该数之间所有整数的和

until语句的结构

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

until语句示例1:

计算1-100的和值。通过循环累加的方式计算1-100的和值

复制代码
#!/bin/bash
i=1
sum=0
until [ $i -gt 100 ]
  do
    sum=$(($sum+$i))
   let i++
  done
   echo "1-50的累加和为:$sum"

跳出循环

continue跳出循环

表示满足continue条件时跳出循环,但是不影响后续循环执行

复制代码
#!/bin/bash 
for i in {1..5} #for循环5次 从i=1 开始到 i=5
do
if [ $i -eq 3 ] #if判断语句,若$1等于3 则执行then的内容
then
continue    #当$i=3时跳出循环但不影响后面循环
fi          #结束if语句
echo$i      #每执行一次for循环输出一次$i

done        #for循环结束语句

break跳出循环

在某个循环中遇到break直接结束此次循环,但是不影响外边嵌套的循环。

break [数字] 结束数字中的几次循环,若为2则结束自己所在循环和外边嵌套的一层循环,若为3则结束自己所在循环和外边嵌套的2层循环

复制代码
#!/bin/bash
for j in {1..3}   #第一层for循环,j=1,2,3各执行一次do的内容
do                #第一层for循环的执行内容
for i in {1..5}   #第二层for循环,i=1,2,3,4,5各执行一次do的内容
do                #第二层for循环的执行内容   
if [ $i -eq 3 ]   #第二层for循环中添加的if判断语句,当$i=3是执行then内容
then
break             #第二层for循环判断语句执行命令,break结束循环
fi                #if语句结束
echo "$i"         #第二层for循环语句执行每循环一次输出$i
done              #第二层for循环语句结束标志
done              #第一层for循环语句结束标志

具体来说,这段脚本的执行过程如下:
外部循环 for j in {1...3} 循环执行三次,j 分别等于 1、2、3。
在每次外部循环开始时,内部循环 for i in {1...5} 循环执行五次,i 分别等于 1、2、3、4、5。
在内部循环中,当 i 等于 3 时,执行 break 跳出循环。
在内部循环中,使用 echo "$i" 打印当前的数字序列。
在内部循环执行完毕后,外部循环继续执行,直到执行完三次为止。

常用循环脚本实例

循环打印9*9乘法表

  1. 第一步for循环打印一行9个*号
  2. 第二步再添加一个for循环打印一个9行9列的*号正方形
  3. 第三步将号正方形斜砍一般形成99乘法表的基本格式
  4. 第四步将号99乘法表格式用乘法算式替换
复制代码
#!/bin/bash
for ((i=1;i<=9;i++))
do
    for ((j=1;j<=i;j++))
    do
      echo -ne "${i}*${j}=$[$i*$j]\t"
      done
     echo ""
done
复制代码
#!/bin/bash
#99乘法表
for ((second=1; second<=9; second++))
do
    for ((first=1;first<=second;first++))
    do
    echo -n -e "${first}*${second}=$[first*second]\t"
    done
    echo ''
done

数字累加脚本(1-100)

  1. 累加需要用到循环,已知循环次数时使用for循环
  2. 也可以使用while循环达到累加条件时结束循环
复制代码
#!/bin/bash
sum=0         #定义变量sum初始值为0
for i in {1..100} #for循环 i取值从1到100
do
sum=$[ i+sum ]
#let sum=$i+$sum    #每次循环内容计算变量i+sum的值赋值给sum,二选一
done              #for语句结束标志
echo "1-100累加值为:$sum"  #循环结束后输出内容

购物

逛淘宝选购商品,每家商店有五种商品选购(衣服500元,裤子400元,鞋子350元,帽子150元,袜子50元),每次选购完或不买都会提示用户是否继续逛下一家商店,如果不再继续逛的话进行购物车结算总额。

复制代码
#!/bin/bash
i=1
sum=0
 
while [ $i -le 5 ]
do
        echo "进入第$i家商店"
        read -p "是否进入看看(yes/no)" doing
        while [ $doing = "yes" ]
         do
          echo "1:衣服 ¥200"
          echo "2:鞋子 ¥180"
          echo "3:帽子 ¥50"
          echo "4:裤子 ¥190"
        read -p "请选择需要购买的商品序列号:" num
        case $num in
        1)
         echo "衣服购买成功"
          expr $[sum+=200] &>/dev/null
        ;;
 
        2)
         echo "鞋子购买成功"
          expr $[sum+=180] &>/dev/null
        ;;
 
        3)
         echo "帽子购买成功"
          expr $[sum+=50] &>/dev/null
        ;;
 
        *)
         echo "裤子购买成功"
          expr $[sum+=190] &>/dev/null
        ;;
        esac
        read -p "是否进行购买(yes/no)" doing
done
let i++
if [ $doing = "no" ]
        then continue
fi
done
echo "购物的总价为:$sum"

shell 计算器

复制代码
  #!/bin/bash
read -p "请输入第一个整数:" num1
read -p "请输入运算符:加(+);减(-);乘(x);除(/);趋于(%):" fh
read -p "请输入第二个整数:" num2
case $fh in
\+)
   num=$(($num1+$num2))
  echo "结果为:$num"
;;
\-)
   num=$(($num1-$num2))
   echo "输入结果为:$num"
;;
\*)
   num=$(($num1*$num2))
   echo "输入结果为:$num"
;;
\/)
   num=$(($num1/$num2))
   echo "输入结果为:$num"
;;
\%)
   num=$(($num1%$num2))
    echo "输入结果为:$num"
;;
*)
   echo "输入不合法"
esac

正等腰三角形

复制代码
for ((i=1;i<=9;i++))
do
    for ((j=9;j>=i;j--))
     do
       echo -n " "
     done
    for ((n=1;n<=i;n++))
     do
       echo -n "*"
     done
    for ((m=2;m<=i;m++))
     do
       echo -n "*"
     done
   echo ""
done

等腰梯形

复制代码
#!/bin/bash
for ((i=1;i<=10;i++))
do
    for ((j=10;j>=i;j--))
     do
       echo -n " "
     done
    for ((n=1;n<=i;n++))
     do
       echo -n "*"
     done
    for ((t=1;t<=4;t++))
     do
       echo -n "*"
      done
    for ((m=1;m<=i;m++))
     do
       echo -n "*"
     done
   echo ""
done

圣诞树

复制代码
#!/bin/bash
for ((i=1;i<=10;i++))
do
    for((j=1;j<=6;j++))
    do
      echo -n " "
    done
     for ((j=10;j>=i;j--))
     do
           echo -n " "
     done
     for ((n=2;n<=j;n++))
     do
           echo -n "*"
     done
     for ((m=4;m<=i;m++))
    do
      echo -n "*"
    done
     echo 
done

for ((i=1;i<=9;i++))
do
  for ((m=1;m<=3;m++))
  do
    echo -n " "
  done
  for ((j=9;j>=i;j--))
    do
      echo -n " "
   done
   for ((n=1;n<=i;n++))
   do
      echo -n "*"
    done
for ((n=1;n<=4;n++))
    do
      echo -n "*"
    done
   for ((n=2;n<=i;n++))
    do
     echo -n "*"
    done

  echo 
done

for ((i=1;i<=9;i++))
do
  for ((j=9;j>=i;j--))
    do
      echo -n " "
   done
   for ((n=1;n<=i;n++))
   do
      echo -n "*"
    done
   for ((n=1;n<=10;n++))
    do
      echo -n "*"
    done
   for ((n=2;n<=i;n++))
    do
     echo -n "*"
    done
 echo 
done


for ((i=1;i<=6;i++))
do
  for ((j=1;j<=11;j++))
  do
    echo -n " "
 done
for ((n=1;n<=7;n++))
 do
   echo -n "*"
done
 echo ""
done

常用转义字符

  1. echo -n 表示不换行输出
  2. echo -e 输出转义字符,将转义后的内容输出到屏幕上
  3. 常用的转义字符如下:
  4. \b 转义后相当于按退格键(backspace),但前提是" \b "后面存在字符;" \b "表示删除前一个字符," \b\b "表示删除前两个字符。
  5. \c 不换行输出,在"\c"后面不存在字符的情况下,作用相当于 echo -n; 但是当"\c"后面仍然存在字符时,"\c"后面的字符将不会被输出。
  6. \n 换行,被输出的字符从"\n"处开始另起一行。
  7. \f 换行,但是换行后的新行的开头位置连接着上一行的行尾;
  8. \v 与\f相同;
  9. \t 转以后表示插入tab,即横向制表符;
  10. \r 光标移至行首,但不换行,相当于使用"\r"以后的字符覆盖"\r"之前同等长度的字符;但是当"\r"后面不存在任何字符时,"\r"前面的字符不会被覆盖
  11. \ 表示插入" \ "本身;
相关推荐
眠修18 分钟前
Kuberrnetes 服务发布
linux·运维·服务器
好奇的菜鸟1 小时前
Docker 配置项详解与示例
运维·docker·容器
xcs194052 小时前
集运维 麒麟桌面版v10 sp1 2403 aarch64 离线java开发环境自动化安装
运维·自动化
BAOYUCompany2 小时前
暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目
运维·服务器
超龄超能程序猿2 小时前
Bitvisse SSH Client 安装配置文档
运维·ssh·github
奈斯ing3 小时前
【Redis篇】数据库架构演进中Redis缓存的技术必然性—高并发场景下穿透、击穿、雪崩的体系化解决方案
运维·redis·缓存·数据库架构
鳄鱼皮坡3 小时前
仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器
运维·服务器
即将头秃的程序媛3 小时前
centos 7.9安装tomcat,并实现开机自启
linux·运维·centos
fangeqin3 小时前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
小Mie不吃饭4 小时前
FastAPI 小白教程:从入门级到实战(源码教程)
运维·服务器