当前位置: 首页 > news >正文

4. 流程控制语句

文章目录

    • 4.1 if 条件语句
      • 4.1.1 单分支
      • 4.1.2 双分支
      • 4.1.3 多分支
    • 4.2 退出程序
    • 4.3 case语句

4.1 if 条件语句

4.1.1 单分支

语法如下:

if <条件表达式>
then指令
fi或者
if <条件表达式>; then指令
fi

使用示例:判断是否已经成功挂载光盘,如果挂载则显示光盘中的文件

# 分析,判断是否拦截,我们可以判断文件的个数,而要得到文件的个数,我们需要是查询文件目录,然后过滤需要的内容,最后进行内容的切割得到最终需要的值。通过这个值来进行判断即可。[root@openEuler ~]# cat ismount.sh
#!/bin/bashnum=`/usr/bin/ls -l /mnt | grep "total" | cut -d" " -f2`if [ $num -eq 0 ] ; thenecho 'no mount'
fi      if [ $num -gt 0 ] ; then/usr/bin/ls -l  /mnt
fi

需求:编写脚本,判断当前的系统剩余内存的大小,如果小于 10M 则输出信息到日志文件中

# 分析:
# 1. 查看内存的使用情况
#    free -m
# 2. 从查看的结果中获取剩余内存的大小
#	 free -m | grep "Mem:"
# 3. 对显示的内容进行压缩,将多个空格压缩为一个空格
#    free -m|grep "Mem:"|tr -s " "
# 4. 对这个剩余内存大小进行判断,如果低于指定的值则输出信息到日志文件中
#    free -m|grep "Mem:"|tr -s " "|cut -d" " -f4[root@openEuler ~]# cat free_memory.sh
#!/bin/bashif [ $(free -m|grep "Mem:"|tr -s " "|cut -d" " -f4) -lt 3000 ] ; then/usr/bin/logger "free memory less 3000M"
fi

需求:编写脚本,判断当前脚本的执行者是否为 root 用户

# 分析:
# 判断当前登录用户有以下几种方式:
# 1. 使用 whoami 命令来得到
# 2. 使用 id -u 命令来得到当前登录用户的编号
# 3. 通过系统变量来获取 echo $USER
# 4. 通过用户编号的变量来获取 echo $UID[redhat@openEuler ~]$ cat user_info.sh 
#!/bin/bashif [ $USER != "root" ]; thenecho "please use root user operater"
fi

4.1.2 双分支

语法:

if <条件表达式1>; then指令
else指令
fi

需求:判断光盘是否挂载,如果挂载则显示挂载目录下的内容,否则执行挂载命令

[root@openEuler ~]# cat mounted.sh 
#!/bin/bashif [ $(/usr/bin/ls -l /mnt|grep "total"|cut -d" " -f2) -eq 0 ]; thenecho "mounting....."/usr/bin/mount /dev/sr0 /mnt
else/usr/bin/ls -l /mnt
fi[root@openEuler ~]# bash mounted.sh 
mounting.....
mount: /mnt: WARNING: source write-protected, mounted read-only.
[root@openEuler ~]# bash mounted.sh 
total 510
dr-xr-xr-x. 2 root root   2048 Jan  2 15:46 docs
dr-xr-xr-x. 3 root root   2048 Jan  2 15:43 EFI
dr-xr-xr-x. 3 root root   2048 Jan  2 15:43 images
dr-xr-xr-x. 2 root root   2048 Jan  2 15:43 isolinux
dr-xr-xr-x. 2 root root   2048 Jan  2 15:46 ks
dr-xr-xr-x. 2 root root 501760 Jan  2 15:46 Packages
dr-xr-xr-x. 2 root root   4096 Jan  2 15:46 repodata
-r--r--r--. 1 root root   3033 Jan  2 15:46 RPM-GPG-KEY-openEuler
-r--r--r--. 1 root root   2198 Jan  2 15:46 TRANS.TBL

需求:判断本地仓库是否创建,如果创建则显示已创建,否则这个本地仓库文件。

# 分析
# 1. 查看所有本地仓库的配置内容
#    cat /etc/yum.repos.d/*.repo
# 2. 从本地仓库的配置信息获取 baseurl 值
#    cat /etc/yum.repos.d/*.repo | grep "baseurl"
# 3. 从过滤的内容中获取最后一条
#    cat /etc/yum.repos.d/*.repo | grep "baseurl"|tail -1
# 4. 判断是否有本地仓库的配置[root@openEuler ~]# cat repos.sh 
#!/bin/bashresult=`cat /etc/yum.repos.d/*.repo | grep "baseurl"|tail -1|cut -d"=" -f2`if [ "$result" == "/mnt" ] ; thenecho "created repository"
elseecho "creating....."
/usr/bin/cat>/etc/yum.repos.d/yum.repo<<"EOF"
[baseOS]
name=baseOS
baseurl=/mnt
gpgcheck=0
EOFecho "created success"
fi

练习:判断 sshd 进程是否运行,如果服务未启动则启动相应服务。

# 分析
# 1. 查看进程
#   ps -ef | grep sshd | grep -v grep|wc -l
# 2. 查看端口
#   netstat -lntup | grep 22 | wc -l
#   ss -lntup|grep -w 22|wc -l
# 3. 查看服务
#   systemctl is-active sshd[root@openEuler ~]# cat sshd.sh 
#!/bin/bashsshd_process_count=`ps -ef|grep sshd|grep -v grep|wc -l`
sshd_port=`ss -lntup|grep -w 22|wc -l`
sshd_service=`systemctl is-active sshd`# if [ "$sshd_service" == "active" ]; thenif [ $sshd_process_count -gt 1 ]; thenecho "sshd is running....."
elseecho "sshd is not running"systemctl start sshd &> /dev/nullsleep 1echo "sshd start"
fi

练习:检查主机是否存活,并输出结果

# 分析:
# 1. 测试主机是否存活,使用 ping 命令即可。
#   ping -c3 192.168.72.150 &>/dev/null[root@openEuler ~]# cat ping.sh 
#!/bin/bashhost="192.168.72.150"
ping -c3 -W1 $host &>/dev/nullif [ $? -eq 0 ] ; thenecho "host $host is active."
elseecho "host $host is not active"
fi[root@openEuler ~]# 
[root@openEuler ~]# bash ping.sh 
host 192.168.72.150 is active.

4.1.3 多分支

语法:

if <条件表达式1>; then指令1
elif <条件表达式2>; then指令2
...
else指令n
fi

当整个 if elif 结构是不满足第一个条件进,则执行进入第二个条件表达式,如果依然不满足则进入第三个,依次类推,当都不满足时则进入 else 语句中,如果某个条件满足则执行对应的指令。

使用示例:接收两个整数并比较其大小。

# 分析:
# 1. 接收数据,我们需要使用 read 指令
# read -p "提示信息" a b
# 2. 对这两个数进行比较# 实现:
[root@openEuler ~]# cat compare.sh 
#!/bin/bashread -p "please input two number:" a bif [ $a -eq $b ]; thenecho "$a equals $b"
elif [ $a -gt $b ]; thenecho "$a greate then $b"
elif [ $a -lt $b ]; thenecho "$a less then $b"
elseecho "error"
fi[root@openEuler ~]# bash compare.sh 
please input two number:2 3
2 less then 3[root@openEuler ~]# bash compare.sh 
please input two number:5 2
5 greate then 2[root@openEuler ~]# bash compare.sh 
please input two number:5 5
5 equals 5# 实现方式二:通过执行脚本时传参,而不是通过 read 来读取
[root@openEuler ~]# cat compare2.sh 
#!/bin/bashif [ $# -ne 2 ]; thenecho "parameter must two"exit 1
fiif [ $1 -eq $2 ]; thenecho "$1 equals $2"
elif [ "$1" -gt "$2" ]; thenecho "$1 greate than $2"
elseecho "$1 less than $2"
fi[root@openEuler ~]# bash compare2.sh  4 
parameter must two
[root@openEuler ~]# bash compare2.sh
parameter must two
[root@openEuler ~]# bash compare2.sh  4  5
4 less than 5

使用示例2:根据用户的输入成绩,判断优良中差。

85-100 为优,A

70-84 为良,B

60-69 为合格,C

60以下为不合格,D

# 分析
# 1. 首先接收用户输入的数分,我们将这个分数值存入到变量 score 中
#   read -p "input score" score
# 2. 判断输入的分数是否为空
#    if [ -z $score ] ; then echo "不能为空" fi
# 3. 判断输入的分数是否小于 0 或大于 100
#    if [ $score -lt 0 -o $score -gt 100 ]; then echo "不对" fi
# 4. 判断分数是否在 85 ~ 100 之间
#    if [ $score -ge 85 -a $score -le 100 ]; then echo "A" fi
# 5. 判断分数是否在 70 ~ 84 之间
#    if [ $score -ge 70 -a $score -le 84 ]; then echo "B" fi
# 6. 判断分数是否在 60 ~ 69 之间
#    if [ $score -ge 60 -a $score -le 69 ]; then echo "C" fi
# 7. 判断分数是否在 60 以下
#    if [ $score -lt 60 ]; then echo "D" fi[root@openEuler ~]# cat score.sh 
#!/bin/bashread -p "please your score:" scoreif [ -z $score ] ; thenecho "score not empty"exit 1
elif [[ $score -lt 0 || $score -gt 100 ]] ; thenecho "score must between 0 and 100"exit 2
elif [ $score -ge 85 -a $score -le 100 ] ; thenecho "A"
elif [ $score -ge 70 -a $score -le 84 ] ; thenecho "B"
elif [[ $score -ge 60 && $score -le 69 ]] ; thenecho "C"
elseecho "D"
fi[root@openEuler ~]# bash score.sh
please your score:-1
score must between 0 and 100
[root@openEuler ~]# bash score.sh
please your score:
score not empty
[root@openEuler ~]# 
[root@openEuler ~]# bash score.sh
please your score:59
D
[root@openEuler ~]# bash score.sh
please your score:67
C
[root@openEuler ~]# bash score.sh
please your score:98
A
[root@openEuler ~]# 

说明:如果在判断语句中使用 && 或者 || 时,需要使用双中括号[[ ]]

4.2 退出程序

我们可以在 shell 中使用 exit 命令来退出脚本,并可以返回指定的状态码,以便于后续的判断。它的语法格式为:

exit status

注意:stauts 是一个数字,当值为 0 时表示命令正常结束,当为非 0 时,表示命令执行时出现了错误。

使用示例:在不同的情况下,程序返回不同一状态码。

[root@openEuler ~]# cat exit.sh 
#!/bin/bashecho hello world
echo $?hahaecho $?exit 100
[root@openEuler ~]# bash exit.sh 
hello world
0
exit.sh: line 6: haha: command not found
127
[root@openEuler ~]# echo $?
100
[root@openEuler ~]# 

exit 还可以使用在 if 语句中,使得程序在不同条件下退出

[root@openEuler ~]# cat file_create.sh 
#!/bin/bashif [ -e "$1" ]; thenecho "file $1 exists"exit 1
elseecho "file $1 is not exists"touch $1exit 0
fi	
[root@openEuler ~]# bash file_create.sh aa
file aa is not exists
[root@openEuler ~]# bash file_create.sh aa
file aa exists
[root@openEuler ~]# ll
total 28
-rw-r--r--. 1 root root   0 Mar 31 16:34 aa

4.3 case语句

语法:

case 变量名 in值1)指令1;;值2)指令2;;值n)指令n;;*)默认指令
esac

case 语句会将变量的值与每个值进行比较,如果与某个值相等,则执行该指令,当遇到“;;”符号时,表示退出 case 语句,执行后续代码。如果没有任何一个值与之匹配,则执行 “*” 后面的语句。

使用示例1:由用户从键盘输入一个字符,判断该字符是字母还是数字,以及其他字符,并输出相应的提示信息。

# 分析
# 1. 接收用户输入
# read -p "" key
# 2. 判断是否为空
#  [ -z $key ]
# 3. 判断是否为字母
# [a-z]|[A-Z]
# 4. 判断是否为数字
# [0-9]
# 5. 如果第3步和第4步都没有匹配上,则表示是其他字符[root@openEuler ~]# cat test.sh 
#!/bin/bashread -p "please input character" keyif [ -z $key ] ; thenecho "input must not empty"exit 2
fiif [ $(expr length $key) -ne 1 ] ; thenecho "input length must 1"exit 3
ficase $key in[a-z]|[A-Z])echo "input is letter";;[0-9])echo "input is number";;*)echo "input is other character";;
esac[root@openEuler ~]# bash test.sh 
please input character: c
input is letter
[root@openEuler ~]# bash test.sh 
please input character: 4
input is number
[root@openEuler ~]# bash test.sh 
please input character: ;
input is other character

使用示例2:将if语句中的多分支案例使用 case 来实现。

[root@openEuler ~]# cat score2.sh 
#!/bin/bashread -p "input your score: " scorecase ${score} in8[5-9]|9[0-9]|100)echo "A";;7[0-9]|8[0-4])echo "B";;6[0-9])echo "C";;*)echo "D"
esac[root@openEuler ~]# bash score2.sh 
input your score: 59
D
[root@openEuler ~]# bash score2.sh 
input your score: 67
C
[root@openEuler ~]# bash score2.sh 
input your score: 75
B
[root@openEuler ~]# bash score2.sh 
input your score: 89
A

练习:开发一个 rsync 起停脚本

[root@openEuler ~]# cat my_rsync.sh 
#!/bin/bashif [ "$#" -ne 1 ] ; thenecho "Usage: $0 {start|stop|restart}"exit 1
ficase "$1" in"start")/usr/bin/rsync --daemonsleep 1if [ `ss -lntup|grep rsync|wc -l` -ge 1 ] ; thenecho "rsync is start"exit 0fi;;"stop")killall rsync &>/dev/nullsleep 1if [ `ss -lntup|grep rsync|wc -l` -eq 0 ] ; thenecho "rsync is stop"exit 0fi;;"restart")if [ `ss -lntup|grep rsync|wc -l` -ge 1 ] ; thenkillall rsync &>/dev/nullsleep 1fi/usr/bin/rsync --daemonsleep 1echo "rsync is restarted"exit 0;;*)echo "Usage: $0 {start|stop|restart|"esac[root@openEuler ~]# bash my_rsync.sh 
Usage: my_rsync.sh {start|stop|restart}
[root@openEuler ~]# bash my_rsync.sh start
rsync is start
[root@openEuler ~]# bash my_rsync.sh stop
rsync is stop
[root@openEuler ~]# bash my_rsync.sh restart
rsync is restarted

相关文章:

  • 【软考的系统分析师的考题考点解析2025】
  • 【面试干货】MySQL 三种锁的级别(表级锁、行级锁和页面锁)
  • 力扣每日一题 6/8
  • expect自动化交互应用程序工具
  • 【文件导出2】导出html文件数据
  • C# 绘图及古诗填字
  • Android基础-进程间通信
  • 熟悉的软件架构风格及详细介绍
  • 自动驾驶人工智能
  • 【深度学习】之 卷积(Convolution2D)、最大池化(Max Pooling)和 Dropout 的NumPy实现
  • arm系统中双网卡共存问题
  • 区块链共识机制技术一--POW(工作量证明)共识机制
  • Transformer论文精读
  • App UI 风格,引领时尚
  • 无头+单向+非循环链表的实现
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 10个确保微服务与容器安全的最佳实践
  • Android Volley源码解析
  • Android 架构优化~MVP 架构改造
  • C# 免费离线人脸识别 2.0 Demo
  • chrome扩展demo1-小时钟
  • C学习-枚举(九)
  • ES学习笔记(12)--Symbol
  • exif信息对照
  • iOS | NSProxy
  • iOS编译提示和导航提示
  • Java IO学习笔记一
  • Laravel 菜鸟晋级之路
  • Logstash 参考指南(目录)
  • PAT A1092
  • Sass 快速入门教程
  • spring boot 整合mybatis 无法输出sql的问题
  • Spring Cloud Feign的两种使用姿势
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 判断客户端类型,Android,iOS,PC
  • 前端之Sass/Scss实战笔记
  • 前端自动化解决方案
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 小试R空间处理新库sf
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #QT(一种朴素的计算器实现方法)
  • (26)4.7 字符函数和字符串函数
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (篇九)MySQL常用内置函数
  • (三) diretfbrc详解
  • (转) Face-Resources
  • (转)Google的Objective-C编码规范
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .bat批处理出现中文乱码的情况
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件