文章目录
-
- [4.1 if 条件语句](#4.1 if 条件语句)
-
- [4.1.1 单分支](#4.1.1 单分支)
- [4.1.2 双分支](#4.1.2 双分支)
- [4.1.3 多分支](#4.1.3 多分支)
- [4.2 退出程序](#4.2 退出程序)
- [4.3 case语句](#4.3 case语句)
4.1 if 条件语句
4.1.1 单分支
语法如下:
bash
if <条件表达式>
then
指令
fi
或者
if <条件表达式>; then
指令
fi
使用示例:判断是否已经成功挂载光盘,如果挂载则显示光盘中的文件
bash
# 分析,判断是否拦截,我们可以判断文件的个数,而要得到文件的个数,我们需要是查询文件目录,然后过滤需要的内容,最后进行内容的切割得到最终需要的值。通过这个值来进行判断即可。
[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 则输出信息到日志文件中
bash
# 分析:
# 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 用户
bash
# 分析:
# 判断当前登录用户有以下几种方式:
# 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 双分支
语法:
bash
if <条件表达式1>; then
指令
else
指令
fi
需求:判断光盘是否挂载,如果挂载则显示挂载目录下的内容,否则执行挂载命令
bash
[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
需求:判断本地仓库是否创建,如果创建则显示已创建,否则这个本地仓库文件。
bash
# 分析
# 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 进程是否运行,如果服务未启动则启动相应服务。
bash
# 分析
# 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
练习:检查主机是否存活,并输出结果
bash
# 分析:
# 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 多分支
语法:
bash
if <条件表达式1>; then
指令1
elif <条件表达式2>; then
指令2
...
else
指令n
fi
当整个 if elif 结构是不满足第一个条件进,则执行进入第二个条件表达式,如果依然不满足则进入第三个,依次类推,当都不满足时则进入 else 语句中,如果某个条件满足则执行对应的指令。
使用示例:接收两个整数并比较其大小。
bash
# 分析:
# 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
bash
# 分析
# 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 命令来退出脚本,并可以返回指定的状态码,以便于后续的判断。它的语法格式为:
bash
exit status
注意:stauts 是一个数字,当值为 0 时表示命令正常结束,当为非 0 时,表示命令执行时出现了错误。
使用示例:在不同的情况下,程序返回不同一状态码。
bash
[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 语句中,使得程序在不同条件下退出
bash
[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语句
语法:
bash
case 变量名 in
值1)
指令1
;;
值2)
指令2
;;
值n)
指令n
;;
*)
默认指令
esac
case 语句会将变量的值与每个值进行比较,如果与某个值相等,则执行该指令,当遇到";;"符号时,表示退出 case 语句,执行后续代码。如果没有任何一个值与之匹配,则执行 "*" 后面的语句。
使用示例1:由用户从键盘输入一个字符,判断该字符是字母还是数字,以及其他字符,并输出相应的提示信息。
bash
# 分析
# 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 来实现。
bash
[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 起停脚本
bash
[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