4. 流程控制语句

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 <条件表达式1>; 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<<"EOF"
[baseOS]
name=baseOS
baseurl=/mnt
gpgcheck=0
EOF
	echo "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/bash

sshd_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" ]; then

if [ $sshd_process_count -gt 1 ]; then
	echo "sshd is running....."
else
	echo "sshd is not running"
	systemctl start sshd &> /dev/null
	sleep 1
	echo "sshd start"
fi


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

# 分析:
# 1. 测试主机是否存活,使用 ping 命令即可。
#   ping -c3 192.168.72.150 &>/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 <条件表达式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/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 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/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

相关推荐

  1. 4. 流程控制语句

    2024-06-10 09:44:01       6 阅读
  2. js流程控制语句

    2024-06-10 09:44:01       28 阅读
  3. Python流程控制语句

    2024-06-10 09:44:01       29 阅读
  4. MySQL-流程控制语句

    2024-06-10 09:44:01       11 阅读
  5. 4. 深入 Python 流程控制

    2024-06-10 09:44:01       29 阅读

最近更新

  1. Ubuntu 移除netplan

    2024-06-10 09:44:01       0 阅读
  2. ubuntu设置GPU功率

    2024-06-10 09:44:01       0 阅读
  3. MatLab中无穷量和非数值量

    2024-06-10 09:44:01       0 阅读
  4. 网络安全练气篇——常见服务端口对应漏洞

    2024-06-10 09:44:01       0 阅读
  5. postman接口测试工具详解

    2024-06-10 09:44:01       0 阅读
  6. C语言运算类型有哪些

    2024-06-10 09:44:01       0 阅读
  7. 【Redis】为什么是单线程?为什么这么快呢?

    2024-06-10 09:44:01       0 阅读

热门阅读

  1. vscode 好用的插件

    2024-06-10 09:44:01       5 阅读
  2. 23种设计模式——创建型模式

    2024-06-10 09:44:01       5 阅读
  3. 2024年6月10日--6月16日(渲染+ue独立游戏)

    2024-06-10 09:44:01       7 阅读
  4. Terminal Multiplexer的使用

    2024-06-10 09:44:01       5 阅读
  5. 什么情况下需要用到动态IP

    2024-06-10 09:44:01       4 阅读
  6. node-mysql中占位符?的使用

    2024-06-10 09:44:01       5 阅读
  7. 007 CentOS 7.9 apache-tomcat-9.0.89安装及配置

    2024-06-10 09:44:01       5 阅读
  8. 设计模式-策略模式

    2024-06-10 09:44:01       5 阅读
  9. 密码学及其应用——安全邮件、公钥密码学和PKI

    2024-06-10 09:44:01       6 阅读
  10. 语法、语义、语用与向量化

    2024-06-10 09:44:01       5 阅读
  11. 给gRPC增加负载均衡功能

    2024-06-10 09:44:01       4 阅读