shell脚本基础之循环语句

目录

一、循环语句的概念

二、for循环语句

1、列表循环

2、列表for循环案例大全

案例一

案例二

案例三

案例四

案例五

案例六

案例七

案例八

3、不带列表循环

4、类似C语言风格的for循环

5、for循环总结

三、while循环语句

1、while循环语句格式

2、while死循环

3、跳出循环

[3.1 exit](#3.1 exit)

[3.2 break](#3.2 break)

[3.3 continue](#3.3 continue)

[3.4 区别](#3.4 区别)

4、while循环案例大全

案例一

案例二

案例三

案例四

案例五

四、until循环语句

1、until循环语句格式

2、until死循环

3、until循环案例大全

案例一

案例二


一、循环语句的概念

shell脚本的循环语句用于重复执行一系列命令或操作。它允许您根据条件或计数器来控制循环的执行次数,通常有进入循环的条件和退出循环的条件

重复运行次数:

  • 循环次数事先已知,如for循环语句

  • 循环次数事先未知,如while、until循环语句

二、for循环语句

for循环用于遍历一个列表或范围内的元素,并对每个元素执行相同的操作。通常使用for关键字和in关键字来指定要遍历的列表

1、列表循环

bash 复制代码
for  变量名  in   list
do
     command
done

注:

list支持**{ ...... }** 和 ` 命令 `(即调用命令执行的结果)


注:

command:可调用前面的变量,也可直接使用命令

2、列表for循环案例大全

案例一

将/opt下所有文件的后缀改为.txt

bash 复制代码
#!/bin/bash
#将/opt下所有文件的后缀改为.txt
for i in `ls /opt`
do
name=`echo $i|cut -d"." -f1`
mv /opt/$i /opt/${name}.txt
done

案例二

如何实现批量修改格式为:2220_陈辰.jpg(示例)

步骤一: 将name.txt的内容导出成文件

bash 复制代码
#!/bin/bash
#将文件里的内容导出成文件,方便改名的操作
for i in `cat /opt/name.txt`
do
touch /data/$i
done

步骤二:批量改名

bash 复制代码
#!/bin/bash
for i in `ls /data`
do
a=`echo ${i} | cut -d "_" -f1`
b=`echo ${i} | cut -d "_" -f2`
mv /data/${i} /data/${b}_${a}.jpg
done

案例三

步骤一:模拟环境,生成日期日志

bash 复制代码
#!/bin/bash
#模拟环境,生成日期日志
PDIR=/data/test
for i in {1..365};do 
 DIR=`date -d "-$i day" +%F`
 mkdir -pv $PDIR/$DIR cd $PDIR/$DIR
 for j in {1..10};do
 touch $RANDOM.log
 done
done

现在如何批量将日志分层放置,实现这样的放置格式:年-月-->日期-->日志

步骤二:日志分层放置

bash 复制代码
#!/bin/bash
a=/data/test
cd $a || { echo "无法进入 $a";exit 1;}
for i in *;do
YYYY_MM=`echo $i | cut -d"-" -f1,2`
DD=`echo $i |cut -d"-" -f3`
[ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null
mv $i/* $YYYY_MM/$DD
done
rm -rf $a/*-*-*

案例四

计算

(1)计算1+2+3+4....+100的和

方法一:

bash 复制代码
#!/bin/bash
for i in {1..100}
do
sum=$[i+sum]
done
echo "求总和结果为:$sum"

方法二:

bash 复制代码
sum=0
for i in `seq 100`
do
let sum+=$i
done
echo "求总和结果为:$sum"

(2) 计算1~100内的奇数和

方法一:

bash 复制代码
#!/bin/bash
for i in {1..100..2}
do
sum=$[i+sum]
done
echo "求奇数和结果为:$sum"

方法二:

bash 复制代码
sum=0
for i in `seq 1 2 100`
do
let sum+=$i
done
echo "求奇数和结果为:$sum"

(3)计算1~100内的偶数和

方法一:

bash 复制代码
#!/bin/bash
for i in {0..100..2}
do
sum=$[i+sum]
done
echo "求偶数和结果为:$sum"

方法二:

bash 复制代码
sum=0
for i in `seq 0 2 100`
do
let sum+=$i
done
echo "求偶数和结果为:$sum"

案例五

判断文件内的用户是否存在,如果用户不存在需要新建

bash 复制代码
#!/bin/bash
#判断/data/name.txt内的用户是否存在,如果用户不存在需要新建
for i in `cat /data/name.txt`
do
id $i &> /dev/null
  if [ $? -eq 0 ];then
  echo "${i} 用户已存在!"
  else
  useradd $i
  echo 123456 | passwd --stdin $i &> /dev/null
    if [ $? -eq 0 ];then
    echo "${i} 用户新建成功!"
    else
    echo "${i} 用户新建失败!"
    fi
  fi
done

案例六

检测172.16.12.0网段的主机网络是否能联通

方法一:

bash 复制代码
#!/bin/bash
{
for i in {1..254}
do
ping -c2 -W2 172.16.12.$i &>/dev/null
if [ $? -eq 0 ];then
echo "172.16.12.$i is online" >> /data/on.txt
else
echo "172.16.12.$i is offline" >> /data/off.txt
fi
done
}&

方法二:

bash 复制代码
#!/bin/bash
for i in {1..254}
do
{
ping -c2 -W2 172.16.12.$i &>/dev/null && echo "172.16.12.$i is online" >> /data/on.txt || echo "172.16.12.$i is offline" >> /data/off.txt
}&
done

案例七

(1)如何使用" *"打印长方形

bash 复制代码
#!/bin/bash
#j为行数  i为列数
for j in {1..9}
do
    for i in {1..9}
    do
    echo -e "*\c"     #\c换行
    done
echo
done

(2)如何使用" *"打印正三角形

bash 复制代码
#!/bin/bash
#j为行数  i为列数
for j in {1..9}
do
    for i in `seq $j`
    do
    echo -e "*\c"
    done
echo  #换行
done

(3)如何打印正序九九乘法表

bash 复制代码
#!/bin/bash
#j为行数  i为列数
for j in {1..9}
do
    for i in `seq $j`
    do
    echo -e "${i}x${j}=$[i*j] \t\c"
    #\t tab键可以对齐
    done
echo
done

(4)如何打印倒序九九乘法表

bash 复制代码
#!/bin/bash
for j in {1..9}
do
for i in `seq $[10-$j]`
do
echo -ne " ${i}x`echo $[10-j]`=$[(10 -j)*i]\t"
done
echo
done

案例八

编写垃圾箱脚本

bash 复制代码
#!/bin/bash
WARNING_COLOR="echo -e \E[1;31m"
END="\E[0m"

DIR=/tmp/`date +%F_%H-%M-%S`

mkdir  $DIR
mv $*  $DIR       
${WARNING_COLOR} Move $* to $DIR $END

3、不带列表循环

使用较少,了解即可,注意一定要在运行脚本时添加列表参数

bash 复制代码
for  变量名 
do
     command
done

4、类似C语言风格的for循环

bash 复制代码
for ((expr1;expr2;expr3))
do
       command
done

expr1:定义变量并赋初值
expr2:决定是否循环
expr3:决定循环变量如何改变,决定循环什么时候退出

| ++ | 自身变量+1 |
| -- | 自身变量-1 |
| +=5 | 自身变量+5 |
| -=5 | 自身变量-5 |
| *=5 | 自身变量*5 |
| /=5 | 自身变量/5 |

%=5 自身变量%5

如何利用类似C语言风格的for循环语句,计算1+2+3+4....+100的和

bash 复制代码
#!/bin/bash
sum=0
for ((i=0;i<=100;i++))
do
let sum+=i
done
echo $sum

如何利用类似C语言风格的for循环语句,打印出九九乘法表

bash 复制代码
#!/bin/bash
for ((i=1;i<=9;i++))
do
    for ((j=1;j<=i;j++))
    do
    echo -e "${i}x${j}=$[i*j] \t\c"
    done
echo
done

5、for循环总结

执行机制:

  • 依次将列表中的元素赋值给"变量名"; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
  • 如果省略 [in WORDS ... ] ,此时使用位置参数变量 in "$@"

三、while循环语句

while循环在给定条件为真时重复执行一系列操作。循环会在每次迭代之前检查条件是否满足,如果满足则执行操作

1、while循环语句格式

bash 复制代码
while
   条件判断为真的表达式
do
   command
done

2、while死循环

死循环一:

bash 复制代码
while  :
do
  command
done

死循环二:

bash 复制代码
while true
do
    command
done

死循环三:

bash 复制代码
#写一个永远为真的表达式,1等于1这个条件永远为真,所以这个脚本会一直循环下去
while [ 1 -eq 1 ]  
do
    command
done

3、跳出循环

3.1 exit

exit命令用于终止整个脚本的执行。可选的参数n是一个整数值,表示脚本的退出状态。通常,0表示成功,非零值表示出现了错误

bash 复制代码
exit  n     #n指定shell的退出状态码
#0表示成功,非0表示有错误发生
exit 1      #表示脚本执行时发生了某种错误

3.2 break

break命令用于跳出循环,例如forwhileuntil循环。当遇到break时,程序会立即跳出当前的循环结构,并执行循环后面的语句

bash 复制代码
break     #跳出当前所处的循环
break  1  #跳出一层循环
break  2  #跳出二层循环
break  n  #跳出n层循环

3.3 continue

continue命令用于结束当前循环的迭代,然后继续下一次迭代。当程序执行到continue时,会立即停止当前迭代并进入下一次循环迭代

bash 复制代码
continue

3.4 区别

  • exit用于完全退出脚本的执行,而breakcontinue用于控制循环结构。
  • break用于完全退出当前循环,而continue用于跳过当前迭代,继续下一次迭代

4、while循环案例大全

案例一

计算1+2+3+4....+100的和

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

案例二

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

bash 复制代码
#!/bin/bash
xz=1
while [ $xz -le 20 ]
do
useradd stu$xz  &>/dev/null

echo 123456|passwd --stdin stu$xz  &>/dev/null
    if [ $? -eq 0 ];then
    echo "${i} 用户新建成功!"
    else
    echo "${i} 用户新建失败!"
    fi
let xz++
done

批量删除以stu开头,按数字顺序进行编号的用户,一共删除20个用户,即stu1、stu2......stu20。

bash 复制代码
#!/bin/bash
xz=1
while [ $xz -le 20 ]
do
userdel stu$xz  &>/dev/null
    if [ $? -eq 0 ];then
    echo "${i} 用户删除成功!"
    else
    echo "${i} 用户删除失败!"
    fi
let xz++
done

案例三

猜价格游戏

bash 复制代码
#!/bin/bash

g=`echo $[RANDOM%800+1]`
time=0
#死循环
while :
do
read -p "请输入商品的价格(1-800):" m
let time++
if [ $g -eq $m ];then
echo "恭喜你猜中啦!商品价格为:${m};您一共猜了${time}次"
exit
#跳出循环
elif [ $m -gt $g -a $m -le 800 -a $m -gt 0 ];then
echo "您猜测的价格过高!"
elif [ $m -lt $g -a $m -le 800 -a $m -gt 0 ];then
echo "您猜测的价格过低!"
else
echo "输入有误!请重新输入!"
fi
done

案例四

网络流量速度计算

bash 复制代码
#!/bin/bash
#定义流量的单位
DW=kb/s
#死循环
while :
do
    #定义某一时间点的提取ens33网卡流量的数值
    OLD_IN=`ifconfig ens33|grep "RX p"|awk '{print $3}'`
    OLD_OUT=`ifconfig ens33|grep "TX p"|awk '{print $3}'`

    #定义下一个时间点的提取ens33网卡流量数值
    NEW_IN=`ifconfig ens33|grep "RX p"|awk '{print $3}'`
    NEW_OUT=`ifconfig ens33|grep "TX p"|awk '{print $3}'`

    #进行流量的计算,默认是Bytes,转换成kb/s
    IN=$[$[$NEW_IN - $OLD_IN]/1024]$DW
    OUT=$[$[$NEW_OUT - $OLD_OUT]/1024]$DW
    sleep 5

    #打印对应的值
    echo -e "接收数据:${IN}\t发送数据:$OUT"
done

案例五

实时监控本机内存和硬盘剩余空间,剩余内存小于500M、根分区剩余空间小于1000M时,发送报警邮件给root管理员

bash 复制代码
#!/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 <<EOF
Insufficient resources, 资源不足
EOF
fi
done

四、until循环语句

until循环与while循环类似,但在给定条件为假时重复执行一系列操作。循环会在每次迭代之前检查条件是否不满足,如果不满足则执行操作

1、until循环语句格式

bash 复制代码
until 条件测试操作
do
命令序列
done

2、until死循环

死循环一:

bash 复制代码
#!/bin/bash

until false
do
    command
done

死循环二:

bash 复制代码
#写一个永远为假的表达式,1等于2这个条件永远为假,所以这个脚本会一直循环下去
until [ 1 -eq 2 ]  
do
    command
done

3、until循环案例大全

案例一

计算1+2+3+4....+100的和

bash 复制代码
#!/bin/bash
sum=0
i=0
until [ $i -gt 100 ]
do
let sum=$i+$sum
let i++
done
echo sum=$sum

案例二

实现在不同终端上的用户登录到同一个服务器,能互发消息

bash 复制代码
#!/bin/bash
#判断输出的参数是否满足条件
if [ $# -lt 2 ];then
echo "位置参数不足,请在脚本后添加用户名及需要发送的消息"
exit 1
fi

#判断用户是否存在
if grep "^$1" /etc/passwd &>/dev/null ;then
echo "该用户存在!"
else
echo "该用户不存在!"
exit 1
fi

#判断用户是否在线
until who | grep $1 &> /dev/null
do
echo "该用户不在线!"
sleep 5
done

echo $2 | write $1
相关推荐
方竞2 分钟前
Linux空口抓包方法
linux·空口抓包
sun0077001 小时前
ubuntu dpkg 删除安装包
运维·服务器·ubuntu
海岛日记1 小时前
centos一键卸载docker脚本
linux·docker·centos
oi771 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
AttackingLin2 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python
吃肉不能购3 小时前
Label-studio-ml-backend 和YOLOV8 YOLO11自动化标注,目标检测,实例分割,图像分类,关键点估计,视频跟踪
运维·yolo·自动化
学Linux的语莫3 小时前
Ansible使用简介和基础使用
linux·运维·服务器·nginx·云计算·ansible
qq_312920113 小时前
docker 部署 kvm 图形化管理工具 WebVirtMgr
运维·docker·容器