shell编程之流程控制-循环语句

Posted 锦衣admin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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编程之流程控制-循环语句的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本编程之流程控制

shell之流程控制

C#基础之流程控制语句详解

shell脚本之流程控制语句

存储过程之流程控制语句

mysql之流程控制语句