shell编程——流程控制

一、if条件判断

1.单分支if条件语句

单分支if条件语句最为简单,就是只有一个判断条件,如果符合条件则执行某个程序,否则什么事情都不做

if [条件判断式];then
	程序
fi

单分支条件语句需要注意几个点:

  • if语句使用fi结尾,和一般语言用大括号结尾不同
  • [条件判断式]就是使用test命令判断所以中括号和条件判断式之间必须有空格
  • then后面跟符合条件之后执行的程序,可以放在[ ]之后,用“;”分割。也可以换行写入,就不需要“;”了,比如单分支if语句还可以这样写:
if [条件判断式]
	then
		程序
fi

例:判断根分区的占比有没有超过80%
在这里插入图片描述

rate=$( df -h | grep /dev/sda2 | awk '{print $5}' | cut -d "%" -f 1 )
if [ $"$rate" -ge 80 ]
	then
		echo "Warning /dev/sd2 is full!"
fi

2.双分支if条件语句

if [条件判断式]
	then 
		条件成立时执行的程序
	else
		条件不成立时执行的另一个程序
fi

例:数据备份

date = $(date +%y%m%d)
# 同步系统时间,把系统时间按照“年月日”格式赋予变量date
size = $(du -sh /var/lib/mysql)
# 统计mysql数据库的大小,并把大小赋予size变量
if [ -d /tmp/dbbak]
# 判断备份目录是否存在,是否为目录
	then
		# 如果判断为真,执行以下脚本
		echo "Date:$date!" > /tmp/dbbak/dbinfo.txt
		# 把当前日期写入临时文件
		echo "Date size:$size" >> /tmp/dbbak/dbinfo.txt
		# 把数据库大小写入临时文件
		cd /tmp/dbbak
		# 进入备份目录
		tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
		# 打包压缩数据库与临时文件,把所有输出丢入垃圾箱(不想看到任何输出)
		rm -rf /tmp/dbbak/dbinfo.txt
		# 删除临时文件
	else
		mkdir /tmp/dbbak
		# 如果判断为假,则建立备份目录
		echo "Date:$date!" > /tmp/dbbak/dbinfo.txt
		# 把当前日期写入临时文件
		echo "Date size:$size" >> /tmp/dbbak/dbinfo.txt
		# 把数据库大小写入临时文件
		cd /tmp/dbbak
		# 进入备份目录
		tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
		# 打包压缩数据库与临时文件,把所有输出丢入垃圾箱(不想看到任何输出)
		rm -rf /tmp/dbbak/dbinfo.txt
		# 删除临时文件
fi

3.多分支if条件语句

if [条件判断式1]
	then 
		当条件判断式1成立时,执行程序1
elif [条件判断式2]
	then
		当条件判断式2成立时,执行程序2
......
else
	当所有条件不成立时,最后执行此程序
fi

例1:用if多分支条件语句来判断一下用户输入的是一个文件,还是一个目录

read -t 30 -p "please input a filename:" file
# 接收键盘的输入,并赋予变量file
if [ -z "$file"]
# 判断file变量是否为空
	then
		echo "Error,please input a filename"
		# 如果为空,执行程序1,也就是输出报错信息
		exit 1
		# 退出程序,并返回值为1(把返回值赋予变量$?)
elif [! -e "$file"]
# 判断file的值是否存在
	then
		echo "Your input is not a file!"
		# 如果不存在,则执行程序2
		exit 2
		# 退出程序,并返回值为2
elif [ -f "$file"]
# 判断file的值是否为普通文件
	then
		echo "$file is a regulare file!"
		# 如果是普通文件则执行程序3
elif [ -d "$file"]
# 判断file的值是否为目录文件
	then
		echo "$file is a directory!"
		# 如果是目录文件,则执行程序4
else
		echo "file is an other file!"
		# 如果以上判断都不是,则执行程序5
fi

例2:加减乘除计算器

read -t 30 -p "Please input num1:" num1
read -t 30 -p "Please input num2:" num2
# 通过read命令接收要计算的数值,并赋予num1和num2
read -t 30 -p "Please input a operator:" ope
# 通过read命令接收要计算的符号,并赋予变量ope

if [ -n "$num1" -a -n "$num2" -a -n "$ope" ]
# 第一层判断,用来判断num1、num2和ope中都有值
	then
	test1=$(echo $num1 | sed's/[0-9]//g')
	test2=$(echo $num2 | sed's/[0-9]//g')
	# 定义变量test1和test2的值为$(命令)的结果
	# 后续命令的作用是,把变量test1的值替换为空。如果能替换为空,证明num1的值为数字
	# 如果不能替换为空,证明num1的值为非数字。我们使用这种方法判断变量num1的值为数字
	# 用同样的方法测试test2变量 
	if [ -z "$test1" -a -z "$test2"]
	# 第二层判断,用来判断num1和num2为数值
	# 如果变量test1和test2的值为空,则证明num1和num2是数字
			then
			# 如果test1和test2是数字,则执行以下命令
			if [ "ope" == '+']
			# 第三层判断用来确认运算符
			# 测试变量$ope中是什么运算符
				then
				value=$(($num1 + $num2))
				# 如果是加号则进行加法运算
			elif [ "$ope" == '-']
				then
				value=$(($num1 - $num2))
				# 如果是减号则进行减法运算
			elif [ "$ope" == '*']
				then
				value=$(($num1 * $num2))
			elif [ "$ope" == '/']
				then
				value=$(($num1 / $num2))
			else 
				echo "Please enter a valid symble"
				# 如果运算符不匹配,提示输入有效的符号
				exit 10
				# 并退出程序,返回错误代码10
			fi
	else
	# 如果test1和test2不为空,说明num1和num2不是数字
		echo "Please enter a valid value"
		# 则提示输入有效的数值
		exit 11
		# 并退出程序,返回错误代码11
	fi
else
	echo "Please input:"
	exit 12
fi

echo "$num1 $ope $num2 : $value"
# 输出数值运算的结果

二、多分支case条件语句

case语句和if…elif…else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系

case $变量名 in
	"值1")
	# 如果变量的值等于值1,则执行程序1
	;;
	"值2")
	# 如果变量的值等于值2,则执行程序2
	...
	*)
	# 如果变量的值都不是以上的值,则执行此程序
	;;
esac

三、for循环

for循环是固定循环,也就是循环时已经知道需要进行几次循环,有时也把for循环称为计数循环。for的语法有如下两种:

# 语法一
for 变量 in 值1 值2 值3...
	do
		程序
	done

这种语法中for循环的次数,取决于in后面值的个数(空格分割),有几个值就循环几次,并且每次循环都把值赋予变量。也就是说,假设in后面有3个值,for会循环3次,第一次循环会把值1赋予变量,第二次循环会把值2赋予变量,以此类推。

# 语法二
for((初始值;循环控制条件;变量变化))
	do
		程序
	done
  • 初始值:在循环开始时,需要给某个变量赋予初始值,如i=1
  • 循环控制条件:用于指定变量循环的次数,如i<=100,则只要i的值小于等于100,循环就会继续
  • 变量变化:每次循环之后,变量该如何变化,如i=i+1,代表每次循环之后,变量i的值都加1

例:从1加到100

s=0
for((i=1;i<=100;i=i+1))
	do
		s=(($s+$i))
	done
echo "The sum of 1+2+...100 is : $s"

1.批量解压缩

# 语法二
cd /root/sh/tar
# 进入到保存压缩包的目录
ls *.tar.gz > tar.log
# 把文件名写入临时文件,目的是把所有压缩包名写入临时日志中,wc才能统计压缩包的个数
# 使用*.tar.gz而不是*,能够避免其他文件干扰,值关注压缩文件
ls *.tgz >> tar.log&>/dev/null
# 同理,将其他压缩格式的压缩包文件名追加到临时日志中
# &>:把正确输出或者错误输出都输出到一个文件中
# /dev/null:相当于一个黑洞,可以理解为回收站

aa=$(cat tar.log | wc -l)
# cat输出内容,wc统计行号,aa中保存了压缩包名的个数,其是for循环的循环控制条件
for (( i = 1; i <= "$aa"; i++ )); do
	bb=$(cat tar.log | awk 'NR=='$i' {print $1}')
	# 每次循环把文件名赋给bb
	tar -zxvf $bb -C /root/sh/tar
	# 把$bb里的值解压缩到指定包内
done
# NR:当前awk所处理的行,是总数据的第几行
  • 需要统计行数,有多少行循环多少次
  • 每次循环时要按照行号把数据提取出来,赋在bb变量
# 语法一
cd /root/sh/tar
ls *.tar.gz > tar.log
ls *.tgz >> tar.log&>/dev/null

for i in $(cat tar.log); do
	tar -zxvf $i
done

2.合法IP判断

# 语法二
grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$" /root/sh/ip.txt > /root/sh/ip_test1.txt
# 先通过正则,把明显不符合规则的ip过滤,把结果保存在/root/sh/ip_test1.txt临时文件中
line=$(wc -l /root/sh/ip_test1.txt | awk '{print $1}')
# 统计test1中有几行ip
echo "" > /root/sh/ip_test.txt
# 清空最终数据文件

for (( i = 1; i < $line; i++ )); do
	cat /root/sh/ip_test1.txt | awk 'NR=='$i'{print}' > /root/sh/ip_test2.txt
	# 第几次循环,就把第几行读入ip_test2.txt文件(此文件中只有一行ip)
	a=$(cat /root/sh/ip_test2.txt | cut -d '.' -f 1)
	b=$(cat /root/sh/ip_test2.txt | cut -d '.' -f 2)
	c=$(cat /root/sh/ip_test2.txt | cut -d '.' -f 3)
	d=$(cat /root/sh/ip_test2.txt | cut -d '.' -f 4)
	# 分别把ip地址的四个数值分别读入变量a,b,c,d
	if ["$a" -lt 1 -o "$a" -gt 255]
	# 如果第一个数值小于1或大于255
		then
			continue
			# 则退出本次循环
	fi

	if ["$b" -lt 0 -o "$b" -gt 255]
		then
			continue
	fi

	if ["$c" -lt 0 -o "$c" -gt 255]
		then
			continue
	fi

	if ["$d" -lt 0 -o "$c" -gt 255]
		then
			continue
	fi
	#依次判断四个ip数值是否超出范围,如果超出。退出本次循环

	cat /root/sh/ip_test2 >> /root/sh/ip_test
	# 如果四个ip数值都符合要求,则把合法ip记录在文件中
done
rm -rf /root/sh/ip_test1
rm -rf /root/sh/ip_test2
# 语法一
grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$" /root/sh/ip.txt > /root/sh/ip_test1.txt
# 先通过正则,把明显不符合的过滤掉,保存到临时文件中
echo "" > /root/sh/ip_valid.txt
# 清空保存数据的文件,最终该文件最终保存有效ip
for i in $(cat /root/sh/ip_test1.txt) do
	a=$(echo "$i" | cut -d "." -f 1)
	b=$(echo "$i" | cut -d "." -f 2)
	c=$(echo "$i" | cut -d "." -f 3)
	d=$(echo "$i" | cut -d "." -f 4)
	# 分别把ip地址的四个数值分别读入变量a,b,c,d
	if ["$a" -lt -o "$a" -gt 255]
	# 如果第一个数值小于1或大于255
		then
			continue
			# 退出本次循环
	fi

	if ["$b" -lt 0 -o "$b" -gt 255]
		then
			continue
	fi

	if ["$c" -lt 0 -o "$c" -gt 255]
		then
			continue
	fi

	if ["$d" -lt 0 -o "$d" -gt 255]
		then
			continue
	fi

	echo "$i" >> /root/sh/ip_valid.txt
done
rm -rf /root/sh/ip_test1.txt

3.批量添加用户

read -p "Please input user name:" -t 30 name
# 让用户输入用户名,把输入保存入变量name
read -p "Please input the number of users:" -t 30 num
# 让用户输入添加用户的数量,把输入保存入变量num
read -p "Please input the password of users:" -t 30 pass
# 让用户输入初始密码,把输入保存入变量pass

if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]
# 判断三个变量不为空
	then
		y=$(echo $num | sed 's/[0-9]//g')
		# 定义变量的值为后续命令的结果
		# 后续命令的作用是把变量num的值替换为空,如果能替换为空,证明num的值为数字
		# 如果不能替换为空,证明num的值为非数字,我们使用这种方法判断变量num的值为数字
		if [ -z "$y" ]
		# 如果变量y的值为空,证明num变量是数字
			then
				for (( i = 1; i < $num; i++ )); do
					# 循环num变量指定的次数
					/usr/sbin/useradd $name$i &> /dev/null
					# 添加用户,用户名变量name的值加变量i的数字
					echo $pass | /usr/bin/passwd --stdin $name$i &> /dev/null
					# 给用户设定初始密码变量pass的值
					chage -d 0 $name$i &> /dev/null
					# 强制用户登录之后修改密码
				done
		fi
fi

4.批量删除用户

user=$(cat /etc/passwd | grep "/bin/bash" | grep -v "root" | cut -d ":" -f 1)
# 读取用户信息文件,提取可以登录用户,取消root用户,截取第一列用户名
for i in $user; do
# 循环,有多少个普通用户,循环多少次
	userdel -r $i
done

四、while循环

while [条件判断式]
	do
		程序
	done

对while循环来讲,只要条件判断式成立,循环就会一直继续,知道条件判断式不成立,循环才会停止

例:1加到100

i=1
s=0
# 给变量i和变量s赋值
while [[ $i -le 100 ]]; do
	# 如果变量i的值小于等于100,则执行循环
	s=$(( $s+$i ))
	i=$(( $i+1 ))
	# 进行数学运算需要双小括号
done
echo "The sum is:$s"

五、until循环

和while循环相反,until循环只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环

until [条件判断式]
	do
		程序
	done

例:1加到100

i=1
s=0
# 给变量i和变量s赋值
until [[ $i -gt 100 ]]; do
	# 循环知道变量i的值大于100,就停止循环
	s=$(( $s+$i ))
	i=$(( $i+1 ))
done
echo "The sum is: $s"

六、特殊流程控制语句

1.exit语句

系统是有exit命令的,用于退出当前用户的登录状态。可是在Shell脚本中,exit 语句是用来退出当前脚本的。也就是说,在Shell脚本中,只要碰到了exit语句,后续的程序就不再执行,而直接退出脚本。exit 的语法如下:

exit [返回值]

如果exit命令之后定义了返回值,那么这个脚本执行之后的返回值就是我们自己定义的返回值。可以通过查询$?这个变量,来查看返回值。如果exit 之后没有定义返回值,脚本执行之后的返回值是执行exit语句之前,最后执行的一条命令的返回值。写一个exit的例子:

read -p "Please input a number:" -t 30 num
# 接收用户的输入,并把输入赋予变量num
y=$(echo $num | sed 's/[0-9]//g')
# 如果变量num的值时数字,则把num的值替换为空,否则不替换
# 把替换之后的值赋予变量y
[-n "$y"] && echo "Error! Please input number!"
# 判断变量y的值如果不为空,输出报错信息,退出脚本,退出返回值为18
echo "The number is: $num" 
# 如果没有退出脚本,则打印变量num中的数字

2.break语句

当程序执行到break语句时,会结束整个当前循环;而continue语句也是结束循环的语句,不过continue语句单次当前循环,而下次循环会继续

for (( i = 0; i < 10; i++ )); do
	if [[ "$i" -eq 4 ]]; then
		break
	fi
	echo $i
done

一旦变量i的值等于4,,整个循环都会跳出,所以只能循环三次,输出:1,2,3

3.continue语句

再来看看continue语句,continue也是结束流程控制的语句。如果在循环中,continue语句只会结束单次当前循环

for (( i = 0; i < 10; i++ )); do
	if [[ "$i" -eq 4 ]]; then
		continue
	fi
	echo $i
done

一旦变量i的值等于4,则会结束本次循环,进入下次循环,所以会输出:1,2,3,5,6,7,8,9,10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源质量:彩色扫描、图片格式不带字体识别、字体图案清晰,质量很好! 作  者:卧龙小三 著,梁昌泰,张琦,黄琨 改编 内容简介:   操作系统Shell编程一直是系统管理员必备高级技能之一。主机管理的上乘之道,就在于尽量让计算机去完成所有的琐事。要达到这个境界,管理者必须具备相当程度的Shell操控能力与Shell程序设计能力,笔者拥有丰富的主机管理实务经验,以及多年的教学经验,能引领读者轻松跨越Bash Shell程序设计的门槛,摆脱菜鸟劳碌的命运,达到轻松管理,主机不出包的境界。   本书完整涵盖Bash 3.x的各项功能,并介绍最新Bash 4.0的重要功能;由简入繁、循序渐进,建立扎实的Bash Shell程序设计基础;各章提供许多范例,充分展示Bash Shell程序设计的技巧;带领读者学习如何设计自动化程序,轻松解决问题,增进工作效率;还包含许多管理实务的技巧,可快速提升读者主机管理的能力。   本书适合系统管理员、网络管理员、架构师及普通学习者参考学习。   主机管理的上乘之道,就在于尽量让电脑去完成所有的琐事。要达到这个境界,管理者必须具备相当程度的Shell操控能力与Shell程序设计能力,卧龙小三拥有丰富的主机管理实务经验,以及多年的教学经验,相信这本《实战Linux Shell编程与服务器管理》必能引领读者轻松跨越Bash Shell程序设计的门槛,摆脱菜鸟劳碌的命运,达到轻松管理,主机不出包的境界。   ■ 完整涵盖Bash 3.x的各项功能,并介绍最新Bash 4.0的重要功能。   ■ 由简入繁、循序渐进,建立扎实的Bash Shell程序设计基础。   ■ 各章提供许多范例,充分展示Bash Shell程序设计的技巧。   ■ 带领读者学习如何设计自动化程序,轻松解决问题,增进工作效率。   ■ 还包含许多管理实务的技巧,可快速提升读者主机管理的能力。 目录: Chapter 1 Shell简介 Chapter 2 布署Bash Shell的环境 Chapter 3 基础概念介绍 Chapter 4 Bash Shell程序的结构 Chapter 5 基本操作介绍 Chapter 6 变量与字符串操作 Chapter 7 高级变量 Chapter 8 算术运算 Chapter 9 流程控制 Chapter 10 函数 Chapter 11 转向 Chapter 12 trap——陷阱触发 Chapter 14 进程管理和工作控制 Chapter 15 历史指令 Chapter 16 使用Shell Script撰写文字和图形接口程序 Chapter 17 文件操作 Chapter 18 主机系统管理 Chapter 19 Bash在TCP/IP方面的运用 Chapter 20 主机安全管理 Chapter 21 备份 附录 Bash 4新功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值