Shell 编程之循环语句---for、while、until

本文详细介绍了Shell脚本中循环语句的使用,包括for、while和until循环,以及如何处理字符串、变量和退出状态。通过多个实例展示了循环在批量用户创建、数字计算、文件读取等场景的应用,并探讨了exit、break和continue在控制流程中的作用。此外,还涉及了多线程执行和IFS内部域分隔符的概念。
摘要由CSDN通过智能技术生成

1 输出字符串或提取shell 变量的值—echo

格式:​echo [参数] [字符串]

1.1 常用参数说明

在这里插入图片描述
示例1:echo -n 表示不换行输出
在这里插入图片描述
示例2:echo -e 输出转义字符,将转义后的内容输出到屏幕上,\b转义后相当于按退格键,但前提是b后面存在字符: b表示删除前一个字符,\b\b表示删除前两个字符
在这里插入图片描述
示例3:\c不换行输出,\n 换行输出,\f 、\v换行输出,\t制表符显示,\r光标移至行首不换行,\表示符号本身
在这里插入图片描述

2 增加、删除、截取字符

字符串长度:${#变量名}
截取字符串:${变量名:开始的下标:截取长度)
字符串追加:变量一+=变量二等同于变量一=变量一变量二
注意:开始的下边是从0开始的

在这里插入图片描述

3 循环语句

脚本执行任务的时候总会遇到需要重复执行的时候,为了节省资源,除了计划任务,我们还可以使用脚本来完成,接下来就是 Shell脚本中的三种循环

3.1 for 循环语句

for 循环,又有人称之为条件循环,或者 for i in ,其实就是 for 循环的特性,次数和给与的条件是成正比的。

for 语句结构
读取不同的变量值,用来逐个执行同一组命令

for 变量名 in 取值列表
do                   
   命令序列
done

在这里插入图片描述
案例一:打印1-10

[root@localhost data]# vim for.sh

#!/bin/bash
for i in {1..10}
do
  echo $i
done

在这里插入图片描述
在这里插入图片描述
案例二:计算从1到10所有整数的和
方法一

[root@localhost data]# vim for9.sh

#!/bin/bash
sum=0
for i in {1..10}
do
  let sum=$[i+sum]
  echo $sum
done
  echo "求和结果是$sum"

在这里插入图片描述
在这里插入图片描述
方法二

[root@localhost data]# vim for7.sh 

#!/bin/bash
sum=0
for((i=1;i<=10;i++))
do
  let sum=$[sum+i]
done
echo $sum

在这里插入图片描述
案例三:批量添加用户,初始密码均设为121212并验证脚本
方法一

[root@localhost data]# vim for10.sh

#!/bin/bash
for i in {1..10}
do
  useradd user$i
#user1 user2 user3 .....
  echo 121212 | passwd --stdin user$i
done

在这里插入图片描述
在这里插入图片描述
案例四:添加几个用户,用户名存放在users.txt文件中,每行一个初始密码均设为121212并验证脚本

#!/bin/bash
for USER in $(cat /root/users.txt)
#USER代表变量名,$()获得cat查看出的结果
do
  useradd $USER
  echo "121212" | passwd --stdin $USER
done

在这里插入图片描述
案例五:根据 IP 地址检查主机状态,使用 ping 命令检测各主机的连通性

[root@localhost data]# vim for2.sh

#!/bin/bash
for i in {1..254}
do
{ping -c 3 192.168.16.$i &>/dev/null
if [ $? -eq 0 ];then
  echo $i主机通顺
else
  echo $i主机不通顺
fi
}&
done
exit

在这里插入图片描述
在这里插入图片描述
案例六:过滤出1到10所有整数的奇偶数
方法一

[root@localhost data]# vim for11.sh

#!/bin/bash
sum=0
for i in `seq 0 2 10`
do
  echo $i
  sum=$[i+sum]
done
  echo "偶数和的结果为$sum"

在这里插入图片描述
在这里插入图片描述

扩充1:多线程

for 循环一般在正常执行的时候是一个进程串行执行的取值列表的

多线程   并行执行
{
..........
}&
wait

例如:

#!/bin/bash
#多线程
for ip in 192.168.16.{1..254}
do
  {
  #-c 3:发3个包  -i 0.5:间隔0.5秒  -W 2:超时2秒 
  ping -c 3-i 0.5 -W 2 $ip &> /dev/null
    if [ $? -eq 0 ];then
      echo "$ip is online" >> /opt/host_ip_online.txt
    else
      echo "$ip is offline" >> /opt/host_ip_offline.txt
    fi
    }&
#增加&符号,代表的是将进程放到后台处理,后台命令之间是不区分先来后到关系的
done
#wait的作用是等待上面所有后台进程都执行完毕后才会去执行后面的语句。如果没用wait后面的语
句是不会等待后台进程的,会造成一些需要有上下文依赖关系的程序执行错误。
wait
cat /opt/host_ip_online.txt
cat /opt/host_ip_offline.txt

在这里插入图片描述

扩充2 :内部域分隔符—IFS

1.查看IFS的值发现env | grep IFS为空,而set | grep IFS有值,说明IFS是局部变量
2.IFS是以空格、反斜杠t(\t制表符)、反斜杠n(\n换行符)来进行分隔的
在这里插入图片描述
例如:

[root@localhost ~]# vim for1.sh

#!/bin/bash
IFS_OLD=$IFS
#IFS=':'
IFS=$IFS':'
for dir in $PATH
do
  echo $dir
done
IFS=$IFS_OLD

在这里插入图片描述
总结:IFS=$'符号’为修改的格式

3.1.1 for 语句综合案例

案例一:提示用户输入一个小于100的整数,并计算从1到该数之间所有整数的和
方法一

#!/bin/bash
read -p "请输入一个小于100的数字:" num
sum=0
for ((i=1;i<=$num;i++))
do
  let sum+=i
done
echo $sum

方法二

#!/bin/bash
read -p "请输入一个小于100的数字:" num
sum=0
for i in $(seq 1 $num) #seq打印1-你输入的值
do
  sum=$[$sum + $i]
  #let sum+=$i
done
echo "和为$sum"

方法三

read -p "请输入小于100的整数:" num
sum=0
if [ $num -le 100 ];then
  for((i=1;i<=$num;i++))
  do
    sum=$[ sum + i]
  done
    echo "1-$num的和为:$sum"
else
  echo "输入错误,请输入小于100的整数"
fi

在这里插入图片描述
案例二:求从1到100所有整数的偶数和、奇数和
方法一

#!/bin/bash
sumji=0
sumou=0
#for ((i=1;i<101;i+=2))
for i in $(seq 1 2 100)  #打印从1开始,每次加2,打印到100
do
  let sumji+=i
done
echo "1到100奇数和为:$sumji"
#for ((i=2;i<101;i+=2))
for i in `seq 0 2 100`  #打印从0开始,每次加2,打印到100
#``反撇在tab上面命令替换,提取命令执行后的输出结果;与$() 用法相同
do
  let sumou+=i
done
echo "1到100偶数和为:$sumou"

在这里插入图片描述
方法二

#!/bin/bash
SUM=0
sum=0
for i in {1..100}
do
  a=$[i % 2]
  if [ $a -eq 0 ];then
    SUM=$[SUM+i]
  else
    sum=$[sum+i]
  fi
#sum=$[$sum + $i]等同于let sum+=$i等同于sum=$[sum+i]
done
echo "1到100的奇数和为$sum"
echo "1到100的偶数和为$SUM"

在这里插入图片描述
案例三:脚本自动生成一个8位随机密码,大小英文字母和数字

字符串长度:${#变量名}
截取字符串:${变量名:开始的下标:截取长度)
字符串追加:变量一+=变量二等同于变量一=变量一变量二
例如:passwd+=$mm等同于passwd=$passwd$mm

注意:开始的下边是从0开始的
[root@localhost shiyan]# vim test9.sh

#!/bin/bash
#定义密码取值范围
String="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

#循环8次
for ((i=1;i<=8;i++))
#for i in {1..8}
do
  num=$[ RANDOM % ${#String} ]  #每次循环随机获取0到字符串长度-1的下标值
#$RANDOM:随机取0--32767之间的整数
  mm=${String:num:1}  #进行字符串截取
#${i:n:m}:i是变量名,n是开始取值的下标,从0开始算起,m是取值长度
  passwd+=$mm   #每次追加生成密码
done
echo "本次生成的密码为:$passwd"

在这里插入图片描述
案例四:使用循环语句将一个0到255之间的十进制数转换成二进制数
方法一

#!/bin/bash 
read -p "请输入一个0-255之间的整数:" num
#给i取值
for i in {128,64,32,16,8,4,2,1}
do
  #定义一个变量,用num-i
  a=$[num - i]
  #如果得到的结果<0
  if [ $a -lt 0 ];then
    #不换行输出0
    echo -n 0
  else
    #不换行输出1
    echo -n 1
    num=$[num - i]
  fi
done
#换行输出
echo ""

在这里插入图片描述
在这里插入图片描述
方法二

#!/bin/bash
read -p "请输入一个0-255之间的整数:" num
if [ $num -ge 0 ] && [ $num -le 255 ];then
    #由于十进制数在0到255之间所以,二进制最多为8位,循环八次
    for ((i=1; i<=8; i++))  #或for i in {1..8}
      do
        #将$num取余数,并赋予$var
        var=$[$num % 2]
        #后面跟一个$sum表示$sum之前的反向输出
        sum=$var$sum
        #$num按循环次数除2取商
        num=$[ $num /2 ]
      done
  echo "转二进制为: $sum"
else
  echo "错误重新输入"
fi

在这里插入图片描述
在这里插入图片描述

3.2 while 循环语句

相对于for,需要知道循环次数。我们只知道停止条件,不知道次数,就需要使用while,直到达到条件
重复测试某个条件,只要条件成立则反复执行

while
当命令判断为假时停止

until
当命令判断为真时停止

在这里插入图片描述
在这里插入图片描述
案例一:计算从1到100所有整数的和

[root@localhost data]# vim while.sh

#!/bin/bash
a=1
sum=0
while [ $a -le 100 ]
do
  sum=$[a+sum]
  let a++
done
  echo $sum 
  所有整数的和为

在这里插入图片描述
案例二:批量添加用户,用户名称以 stu 开头,按数字顺序进行编号,一共添加 5 个用户,即stu1、stu2、……stu5,初始密码均设为121212

[root@localhost data]# vim while1.sh

#!/bin/bash
a=1
while [ $a -le 5 ]
do
  useradd stu$a -M
  echo "121212" |passwd --stdin stu$a
  let a++
done

在这里插入图片描述
在这里插入图片描述
案例三:猜商品价格游戏,通过变量RANDOM获得随机数,提示用户猜测并记录次数,猜中后退出循环

[root@localhost data]# vim while2.sh

#!/bin/bash
i=0
#猜的次数
price=$[RANDOM%1000+1]
#随机出现商品的价格

while true
do
  read -p "请输入你要猜的价格(1-1000):" num
  let i++
        if [ $num -eq $price ]
          then
          echo "恭喜你猜对了!"
          echo "商品的价格为$price,你一共猜了${i}次"
          exit
        elif [ $num -lt $price ]
          then
          echo "你猜小了,请重试!"
        else [ $num -gt $price ]
          echo "你猜大了,请重试!"
        fi
done

在这里插入图片描述
在这里插入图片描述

扩充:while循环文件读入

使用while read ,行读取文件
使用while read ,命令读取文件,目标文件内容以重定向输入的形式输入

while read 变量名
do

done <文件名
或者
cat 文件 | while read 变量名
do

done

在这里插入图片描述

3.3 untli 循环语句

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

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

在这里插入图片描述
案例一:计算 1-10 的和值,通过循环累加的方式计算 1-10 的和值

[root@localhost data]# vim until1.sh

#!/bin/bash
i=1
sum=0
until [ $i -gt 10 ]
#条件不成立才执行命令序列
do
  let sum=$[i+sum]
  let i++
  echo $i
done
  echo "1加到10的结果是$sum"

在这里插入图片描述
在这里插入图片描述
案例二:为指定用户发送在线消息,若用户不在线(未登录系统),则每 5 秒试一次,直至用户登录系统后在发送信息

[root@localhost data]# vim until.sh

#!/bin/bash
until who | grep "$1" &>/dev/null
do
echo $1不在线
sleep 5
done
echo haha | write $1

在这里插入图片描述
在这里插入图片描述

4 退出语句—exit、break、continue

4.1 概念

  • exit:退出shell脚本进程,exit执行后,脚本后面所有的语句都不会执行。exit n(0-255)退出shell脚本进程,并且可以返回指定状态码
  • break跳出当前循环(单层循环),break 2 跳出两层循环(双层循环),循环内break后面的语句不会执行,但是不会影响循环外面的语句
  • continue:终止某次循环的执行,但不会完全终止整个循环,while和until循环中使用需要慎重

例1

[root@localhost ~]# vim for1.sh

#!/bin/bash
for ((i=1;i<=5;i++))   #外层循环
do
  echo "outer 1oop:$i"
  for ((j=1;j<=5;j++)) #内层循环,看作外层循环的一个命令语句
  do
    echo "  inter loop:$j"
  done
done
#外层循环每执行一次,内层循环都要全部执行完毕后,下一次外层循环才能再执行

在这里插入图片描述
在这里插入图片描述
例2

#!/bin/bash
for ((i=1;i<=5;i++))   #外层循环
do
  echo "outer 1oop:$i"
  for ((j=1;j<=5;j++)) #内层循环,看作外层循环的一个命令语句
  do
    echo "  inter loop:$j"
    if [ $j -eq 3 ];then
      exit
    fi
  done
done

在这里插入图片描述
例3

#!/bin/bash
for ((i=1;i<=5;i++))   #外层循环
do
  echo "outer 1oop:$i"
  for ((j=1;j<=5;j++)) #内层循环,看作外层循环的一个命令语句
  do
    echo "  inter loop:$j"
    if [ $j -eq 3 ];then
      break
    fi
  done
done

在这里插入图片描述
在这里插入图片描述
例4

[root@localhost ~]# vim for2.sh

#!/bin/bash
for ((i=1;i<=5;i++))   #外层循环
do
  echo "outer 1oop:$i"
  for ((j=1;j<=5;j++)) #内层循环,看作外层循环的一个命令语句
  do
    if [ $j -eq 3 ];then
      continue
#continue 终止某次循环的执行,但不会完全终止整个循环,while和until循环中使用需要慎重。
    fi
    echo "  inter loop:$j"
  done
done

在这里插入图片描述
在这里插入图片描述

4.2 continue 和 break 比较

break和continue都是用来控制循环结构的,主要是停止循环。

break 有时候我们想在某种条件出现的时候终止循环而不是等到循环条件为false才终止。 这时我们可以使用break来完成。break用于完全结束一个循环,跳出循环体执行循环后面的语句。

continue和break有点类似,区别在于continue只是终止本次循环,接着还执行后面的循环,break则完全终止循环。 可以理解为continue是跳过当次循环中剩下的语句,执行下一次循环。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值