shell编程之流程控制-循环语句
Posted 锦衣admin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程之流程控制-循环语句相关的知识,希望对你有一定的参考价值。
shell编程之流程控制-循环语句
循环语句介绍
循环语句介绍:
工作中总有一些重复性的工作,比如每天都需要执行的备份、每天分析一次业务的日志、每分钟需要检测一次主机状态等等。这些重复性的工作一般使用脚本来完成
对于不需要太频繁执行的任务,可以使用计划任务 + 脚本来完成;但是计划任务时间只能精确到分钟,不能满足更频繁的重复工作。这时候就需要在脚本中使用循环语句
脚本在执行任务,总会遇到需要循环执行的时候。比如说我们需要每个五分钟执行一次ping的操作。除了计划任务,我们还可以使用脚本来完成,这时候就用到循环语句了
循环语句的优点:
- 节省内存的调用,使用循环语句减少代码量
- 结构更清晰
- 节省开发时间成本
串行变成并行的执行方法: &
- 在执行语句后面加上
&
符就代表放入后台执行,前台执行下一个循环语句,这样就不用等待上一条循环语句执行完成再执行下一次循环。
循环语句 - for
特点: 满足条件就执行循环,已知条件循环次数
for 的应用场景: 通过条件明确循环次数
for 语法: 循环主体是 do~done
之间的内容,赋值 和 变量 可以有意义也可以没有意义(只是用于循环的次数而已)
for 循环赋值:
- 直接赋值:
for i in 1 2 3
- 来自一个范围:
for i in {1..10}
- 来自一个命令:
for i in $(seq 10)
注意: for 条件中无法使用shell运算
for 循环语法格式:
命令格式:
# for var in {list}
# do
# command
# command
# ..
# done
参数说明:
var:变量名,容器
{list}:往变量里边存入的值,{list}值可以有意义也可以没有意义
语法说明:
{list} 中的值每存入一次 var 中,就会执行一遍do和done之间的代码。即有几个值就循环多少次
演示:
for i in 1 q w e 3 4 s s s e
do
echo "hello word"
done
=> 演示代码表示输出10次"hello word";代码中可以不调用var变量
赋值方法:
赋值来自一个范围:
# for i in {1..10}
赋值来自一个命令:
# for i in `seq 10`
或
# for i in $(seq 10)
直接赋值:
# for i in 1 2 3 4 5 6 7 8 9 10
for C格式语法
- 仿
C语言
的for风格,双小圆 - 表达式可以与两边括号有空格也可以无空格
- ((初始值
;
条件;
自增或自减运算)) - 注意:for 条件不能和shell的运算混合使用
for C格式语法说明:
for ((;;))
:代表永远为真,死循环
命令格式:
# for (( expr1;expr2;expr3 ))
# do
# command
# command
# ...
# done
选项说明:
expr1:变量的初始值
expr2:变量的条件。绝对是否进行循环的依据
expr3:自增或自减运算(绝对循环什么时候退出)
#l 多变量用法:
# for (( a=1,b=10;a<10,b>5;a++,b-- )) => 注意同一个表达式用,隔开
=> 其中某一个不满足就会结束循环体
演示:
for (( i=1;i<=5;i++ )) => 与 for i in {1..5} 类似
do
echo $i
done
for 嵌套 if
通过有一个打印1-100的奇数和小脚本演示for 嵌套 if
for 嵌套 if 说明:
编写脚本:
# vim for_if.sh
[root@server ~]# vim for_if.sh
#!/bin/bash
# 将1-100通过for赋值给变量
num=0
for i in $(seq 1 100)
do
# 判断变量赋值i是否为奇数,是为真
if (( $i%2 != 0 ))
then
# 将奇数取出,用let命令将奇数相加
# 注意:num不需要加$符号
let num+=$i
fi
done
# 打印1-100奇数和
echo $num
运行脚本:
# sh for_if.sh
[root@server ~]# sh for_if.sh
2500
for 嵌套 for
通过编写一个9*9乘法表来理解 for 嵌套 for 循环
注意:
- 计算机是按行打印的
- 外循环执行结束后就打印一行
- 内循环就是打印列
for 嵌套 for 循环编写9*9乘法表说明:
编写9*9乘法表脚本:
# vim Mt_99.sh
[root@server ~]# vim Mt_99.sh
#!/bin/bash
# 外循环,9*9乘法表有九行,所以取值是1-9
for ((A=1;A<10;A++))
do
# 内循环,明确只有内循环执行完毕才返回外循环执行
# 根据9*9乘法表,明确内循环的取值也是1-9
# 但是内循环的取值是与外循环有关,一列一行,两列两行..九列九行
for ((B=1;B<=A;B++))
do
# 打印输出
echo -n -e "$B*$A=$((A*B))\\t"
done
echo
运行脚本:
# sh Mt_99.sh
[root@server ~]# sh Mt_99.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
for 与数组遍历
- 需要注意数组的索引号
for 与数组遍历存取
说明:
通过for 编写存取数组脚本:
# vim for_array.sh
[root@server ~]# vim for_array.sh
#!/bin/bash
# 通过for循环对数组进行存值
# 存入3人的成绩,并放入数组,需要注意数组的索引号
for i in `seq 0 2`
do
read -p "ID:" ID[$i]
read -p "姓名:" name[$i]
read -p "性别:" gender[$i]
read -p "成绩:" grades[$i]
done
echo -e "ID\\t姓名\\t性别\\t成绩"
# 打印数组的值
for i in `seq 0 2`
do
echo -e "${ID[$i]}\\t${name[$i]}\\t${gender[$i]}\\t${grades[$i]}"
done
运行效果:
# sh for_array.sh
[root@server ~]# sh for_array.sh
ID:1
姓名:李白
性别:男
成绩:98
ID:2
姓名:杜甫
性别:男
成绩:95
ID:3
姓名:苏轼
性别:男
成绩:99
ID 姓名 性别 成绩
1 李白 男 98
2 杜甫 男 95
3 苏轼 男 99
循环控制
循环控制 - sleep(控制)
- 控制循环的节奏,即控制循环的频率
通过一个死循环查看sleep的作用:
编写sleep控制语句脚本:
# vim End_loop.sh
[root@server ~]# vim End_loop.sh
#!/bin/bash
# 条件里面写;;永远为真
for ((;;))
do
echo "ok"
# 使用sleep控制循环,避免狂吃资源,sleep单位是秒
sleep 0.001
done
加入sleep语句控制循环的效果:
循环控制 - break(打断)
- 跳出循环,执行这个循环后面的代码
break 打断循环说明:
编写打印1-7的脚本:
break 打断效果:
# vim break.sh
[root@server ~]# vim break.sh
#!/bin/bash
# 打印1-5的信息
for i in `seq 1 7`
do
echo $i
# 当i=3就结束循环,执行循环后面的代码
if [ $i -eq 3 ]
then
break
fi
done
# break 打断后执行循环后面的代码
echo "执行完毕"
运行效果:
# sh break.sh
[root@server ~]# sh break.sh
1
2
3
执行完毕
循环控制 - continue(跳过某次循环)
- 当代码运行到
break
后,跳过当次循环。循环体内break
后面的代码不执行,重新开始下一次循环
break 跳过某次循环说明:
编写打印1-5的脚本:
continue 跳过某次循环效果:
# vim continue.sh
[root@server ~]# vim continue.sh
#!/bin/bash
# 打印1-5的信息
for i in $(seq 5)
do
# 当i=3的时候跳过这次循环,重新开始循环
if [ $i -eq 3 ]
then
continue
fi
# 打印信息
echo $i
done
echo "打印完毕"
运行效果:
# sh continue.sh
[root@server ~]# sh continue.sh
1
2
4
5
打印完毕
脚本退出命令 - exit
-
代码运行到
exit
命令,直接退出脚本程序,不再执行。 -
退出程序,释放所有该执行该脚本时所申请的资源
exit 退出程序说明:
exit 退出程序效果:
# vim exit.sh
[root@server ~]# vim exit.sh
#!/bin/bash
# 打印1-5的信息
for i in $(seq 5)
do
# 当i=3的时候直接退出程序
if [ $i -eq 3 ]
then
exit
fi
# 打印信息
echo $i
done
echo "打印完毕"
运行效果:
# sh exit.sh => 直接退出程序了,循环体外下面的代码也不执行
[root@server ~]# sh exit.sh
1
2
参数控制命令 - shift
- 使位置参数向左移动,默认每次移动一位
- shift 2 向左移动两位
shift 参数控制说明:
通过外部传参理解shift:
编写脚本:
# vim shift.sh
[root@server ~]# vim shift.sh
#!/bin/bash
for i in `seq 1 $#`
do
echo "当前参数数量:$#"
echo "脚本后面的参数:$@"
echo "第一个参数:$1"
# 通过shift让循环每执行一次参数向左移动一位
# shift 使参数默认向左移动一位
# shift
# shift 2 使参数向左
# shift 2
done
运行脚本:
#l 不加 shift 时:
[root@server ~]# sh shift.sh 1 2 3
当前参数数量:3
脚本后面的参数:1 2 3
第一个参数:1
当前参数数量:3
脚本后面的参数:1 2 3
第一个参数:1
当前参数数量:3
脚本后面的参数:1 2 3
第一个参数:1
#l 使用 shift 时:
[root@server ~]# sh shift.sh 1 2 3
当前参数数量:3
脚本后面的参数:1 2 3
第一个参数:1
当前参数数量:2
脚本后面的参数:2 3
第一个参数:2
当前参数数量:1
脚本后面的参数:3
第一个参数:3
#l 使用 shift 2 时:
[root@server ~]# sh shift.sh 1 2 3
当前参数数量:3
脚本后面的参数:1 2 3
第一个参数:1
当前参数数量:1
脚本后面的参数:3
第一个参数:3
当前参数数量:1
脚本后面的参数:3
第一个参数:3
循环语句 - while
特点: 条件为真时就进入循环,条件为假就退出循环
while的应用场景: 一般应用在未知循环次数的环境
- while 语法表达式需要注意空格
while 循环语法格式:
命令格式:
# while [ 表达式 ] => [ 1 -eq 1 ] 可以变成 (( 1=1 ))
# do
# command
# ...
# done
while 与 shell 运算(比较运算)
while
可以和整数、浮点数、字符串、文件类型进行比较运算
while 与 整数的比较运算
while 与 整数的比较运算说明:
编写脚本:
# vim while_integer.sh
[root@server ~]# vim while_integer.sh
#!/bin/bash
# 给定一个变量,当变量满足打印信息
a=0
# 当a小于4就执行循环
while [ $a -le 4 ];do
echo "$a"
let a++
done
运行脚本:
# sh while_integer.sh
[root@server ~]# sh while_integer.sh
0
1
2
3
4
while 与 浮点数的比较运算
while 与 浮点数的比较运算说明:
编写代码:通过外传参对两个浮点数进行比较
# vim while_float.sh
[root@server ~]# vim while_float.sh
#!/bin/bash
# 通过外部传参对两个浮点数进行整数转换
num1=`echo -e "scale=2;$1*100"|bc|cut -d "." -f1`
num2=`echo -e "scale=2;$2*100"|bc|cut -d "." -f1`
# 对整数进行比较,小于
while [ $num1 -lt $num2 ];do
echo -e "$1 < $2"
exit
done
# 对整数进行比较,大于
while [ $num1 -gt $num2 ];do
echo -e "$1 > $2"
exit
done
# 对整数进行比较,等于
while [ $num1 -eq $num2 ];do
echo -e "$1 = $2"
exit
done
运行脚本:
[root@server ~]# sh while_float.sh 1.1 2.3
1.1 < 2.3
[root@server ~]# sh while_float.sh 34.21 23.87
34.21 > 23.87
[root@server ~]# sh while_float.sh 34.23 34.23
34.23 = 34.23
while 与 字符串的比较运算
while 与 字符串比较说明:
编写脚本:
# vim while_string.sh
[root@server ~]# vim while_string.sh
#!/bin/bassh
# 模拟用户账号登录,只有账号正确才能跳出循环,否则不断循环
read -p "$HOSTNAME login:" account
while [ "$account" != "root" ];do
echo "请重新输入"
read -p "$HOSTNAME login:" account
done
# 账号输入正确打印信息
while [ "$account" = "root" ];do
echo "账号正确"
break
done
运行脚本:
# sh while_string.sh
root@server ~]# sh while_string.sh
server login:sfd
请重新输入
server login:riit
请重新输入
server login:root
while 与 逻辑运算的比较运算
逻辑运算符:与(&&)
、或(||)
、非(!)
-
逻辑与:必须全部条件满足,表达式才判断为真
-
逻辑或:至少有一个条件满足,表达式才判断为真
-
逻辑非:条件为真时,表达式判断为假;条件为假时,表达式判断为真
while 与 逻辑运算说明:
编写一个丈母娘根据要求招女婿的小脚本:
# vim mom_in_son.sh
[root@server ~]# vim mom_in_son.sh
#!/bin/bash
# 面试相亲人的条件
read -p "几套房子?:" house
read -p "几辆车子?:" car
read -p "存款有多少?:" money
# 相亲条件是房子必须有两套,车子两辆,存款必须一百万以上。
# 不符合条件的,用while循环重新面试下一位
while [ $house -lt 1 ] || [ $car -lt 1 ] || [ $money -lt 1000000 ];do
echo "下一位"
read -p "几套房子?:" house
read -p "几辆车子?:" car
read -p "存款有多少?:" money
done
echo "你通过初步面试了,下一步面试你人品,等消息"
运行脚本:
# sh mom_in_son.sh
[root@server ~]# sh mom_in_son.sh
几套房子?:2
几辆车子?:2
存款有多少?:100000
下一位
几套房子?:3
几辆车子?:3
存款有多少?:1000001
你通过初步面试了,下一步面试你人品,等消息
while 的特殊条件:永真或永假
:
:条件是冒号,永远为真
ture
条件是ture,永远为真
false
条件是salse,永远为假
适用于无尽循环环境使用
while 特殊条件说明:
命令格式:
# while : => 永远为真
do
command
..
done
# while true => 永远为真
do
command
..
done
# while false => 永远为假
do
command
..
done
while 嵌套
while 嵌套 if
应用场景: while 循环需要判断条件的时候
条件不要写冲突了
while 嵌套 if说明:
命令格式:
# while [ condition1 ]
# do
# command
# ...
# if [ condition2 ]
# then
# command
# ...
# fi
# done
编写一个while 嵌套 if 的脚本:
# vim while_if.sh
[root@server ~]# vim while_if.sh
/bin/bash
# 打印1<以上是关于shell编程之流程控制-循环语句的主要内容,如果未能解决你的问题,请参考以下文章