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/bash num=`/usr/bin/ls -l /mnt | grep "total" | cut -d" " -f2` if [ $num -eq 0 ] ; then echo '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/bash if [ $(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/bash if [ $USER != "root" ]; then echo "please use root user operater" fi
4.1.2 双分支
语法:
if ; then 指令 else 指令 fi
需求:判断光盘是否挂载,如果挂载则显示挂载目录下的内容,否则执行挂载命令
[root@openEuler ~]# cat mounted.sh #!/bin/bash if [ $(/usr/bin/ls -l /mnt|grep "total"|cut -d" " -f2) -eq 0 ]; then echo "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/bash result=`cat /etc/yum.repos.d/*.repo | grep "baseurl"|tail -1|cut -d"=" -f2` if [ "$result" == "/mnt" ] ; then echo "created repository" else echo "creating....." /usr/bin/cat>/etc/yum.repos.d/yum.repo/dev/null [root@openEuler ~]# cat ping.sh #!/bin/bash host="192.168.72.150" ping -c3 -W1 $host &>/dev/null if [ $? -eq 0 ] ; then echo "host $host is active." else echo "host $host is not active" fi [root@openEuler ~]# [root@openEuler ~]# bash ping.sh host 192.168.72.150 is active.
4.1.3 多分支
语法:
if ; then 指令1 elif ; then 指令2 ... else 指令n fi
当整个 if elif 结构是不满足第一个条件进,则执行进入第二个条件表达式,如果依然不满足则进入第三个,依次类推,当都不满足时则进入 else 语句中,如果某个条件满足则执行对应的指令。
使用示例:接收两个整数并比较其大小。
# 分析: # 1. 接收数据,我们需要使用 read 指令 # read -p "提示信息" a b # 2. 对这两个数进行比较 # 实现: [root@openEuler ~]# cat compare.sh #!/bin/bash read -p "please input two number:" a b if [ $a -eq $b ]; then echo "$a equals $b" elif [ $a -gt $b ]; then echo "$a greate then $b" elif [ $a -lt $b ]; then echo "$a less then $b" else echo "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/bash if [ $# -ne 2 ]; then echo "parameter must two" exit 1 fi if [ $1 -eq $2 ]; then echo "$1 equals $2" elif [ "$1" -gt "$2" ]; then echo "$1 greate than $2" else echo "$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/bash read -p "please your score:" score if [ -z $score ] ; then echo "score not empty" exit 1 elif [[ $score -lt 0 || $score -gt 100 ]] ; then echo "score must between 0 and 100" exit 2 elif [ $score -ge 85 -a $score -le 100 ] ; then echo "A" elif [ $score -ge 70 -a $score -le 84 ] ; then echo "B" elif [[ $score -ge 60 && $score -le 69 ]] ; then echo "C" else echo "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/bash echo hello world echo $? haha echo $? 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/bash if [ -e "$1" ]; then echo "file $1 exists" exit 1 else echo "file $1 is not exists" touch $1 exit 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 aa4.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/bash read -p "please input character" key if [ -z $key ] ; then echo "input must not empty" exit 2 fi if [ $(expr length $key) -ne 1 ] ; then echo "input length must 1" exit 3 fi case $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/bash read -p "input your score: " score case ${score} in 8[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/bash if [ "$#" -ne 1 ] ; then echo "Usage: $0 {start|stop|restart}" exit 1 fi case "$1" in "start") /usr/bin/rsync --daemon sleep 1 if [ `ss -lntup|grep rsync|wc -l` -ge 1 ] ; then echo "rsync is start" exit 0 fi ;; "stop") killall rsync &>/dev/null sleep 1 if [ `ss -lntup|grep rsync|wc -l` -eq 0 ] ; then echo "rsync is stop" exit 0 fi ;; "restart") if [ `ss -lntup|grep rsync|wc -l` -ge 1 ] ; then killall rsync &>/dev/null sleep 1 fi /usr/bin/rsync --daemon sleep 1 echo "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
