目录
[3.1 exit](#3.1 exit)
[3.2 break](#3.2 break)
[3.3 continue](#3.3 continue)
[3.4 区别](#3.4 区别)
一、循环语句的概念
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
命令用于跳出循环,例如for
、while
或until
循环。当遇到break
时,程序会立即跳出当前的循环结构,并执行循环后面的语句
bash
break #跳出当前所处的循环
break 1 #跳出一层循环
break 2 #跳出二层循环
break n #跳出n层循环
3.3 continue
continue
命令用于结束当前循环的迭代,然后继续下一次迭代。当程序执行到continue
时,会立即停止当前迭代并进入下一次循环迭代
bash
continue
3.4 区别
exit
用于完全退出脚本的执行,而break
和continue
用于控制循环结构。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