文章目录
- 一、 条件测试
- 1.1 文件测试
- 1.2 整数值比较
- 1.3 字符串比较
- 1.4 逻辑测试
- 二、 if语句
- 2.1 单分支if语句
- 2.2 双分支的if语句
- 2.3 多分支if语句
- 三、 通过简单脚本实现if语句
- 3.1 单分支if语句应用
- 3.2 双分支if语句应用
- 3.3 多分支if语句应用
一、 条件测试
要使shell脚本具有一定的“智能”,需要区分不同的情况应该执行什么样的操作。在shell环境中可以通过预环境变量($?)来 判断命令的执行是否成功,返回值是0表示成功,非0值表示失败或异常。可以使用专门的测试工具–test命令。
test 命令
test 条件表达式
或者
[ 条件表达式 ] //括号内条件表达式两边必须有空格,这种方式更常用
1.1 文件测试
文件测试操作选项 | 意义 |
-d | 测试是否为目录(Directory) |
-e | 测试目录或文件是否存在(Exist) |
-f | 测试是否为文件(File) |
-r | 测试当前用户是否有权限读取(Read) |
-w | 测试当前用户是否有权限写入 (Write) |
-x | 测试是否设置有可执行(Excute)权限 |
通过条件测试操作返回的预定义变量"$?"的状态值,从而判断条件是否成立。
[root@localhost ~]# [ -d /dev/cdrom ] 判断/dev/cdrom是不是一个目录
[root@localhost ~]# echo $? 输出返回值
1
[root@localhost ~]# [ -d /opt ]
[root@localhost ~]# echo $?
0
我们可以通过命令分隔符"&&“和"echo"一起使用,当条件成立时直接输出一个字符串。”&&"符号表示而且的意思,只有前面的命令执行成功后才会执行后面的。
[root@localhost ~]# [ -d /dev/cdrom ]&& echo yes 判断/dev/cdrom是不是一个目录,是就输出yes
[root@localhost ~]# [ -d /opt/ ]&& echo yes 判断/opt/是不是一个目录,是就输出yes
yes
除了"&&“符号,我们还可以使用”||"符号,表示或者的意思。
[root@localhost ~]# [ -d /opt/ ]&& echo yes || echo no 判断/opt/是不是一个目录,是就输出yes,不是就输出0
yes
[root@localhost ~]# [ -d /dev/cdrom ]&& echo yes || echo no
no
test命令用于判断文件的选项有很多,从文件的个数上判断,我们常用的"-f"选项一般用来判断单个文件,当比较两个文件时。常用的选项有:
- -nt:判断文件A是否比文件B新
- -ot:判断文件是否比文件B旧
- -ef:判断两个文件是否为同一个文件,用来判断两个文件是否能指向同一个inode
1.2 整数值比较
对于给定的两个整数值,判断两个数的大小,通常使用以下命令 :
- -eq :等于(Equal)
- -ne :不等于(Not Equal)
- -gt :大于(Greater Than)
- -lt :小于(Lesser Than)
- -ge :大于或等于(Greater or Equal)
- -le :小于或等于(Lesser or Equal)
[root@localhost ~]# who 查看当前登录用户
root pts/0 2020-07-17 08:49 (14.0.0.1)
root :0 2020-07-17 09:53 (:0)
[root@localhost ~]# num1=`who |wc -l` 将当前登录用户数的值赋给变量num1
[root@localhost ~]# echo $num1
2
[root@localhost ~]# [ $num1 -gt 2 ]&& echo good || echo ok $num1大于2,成立输出good,不成立输出ok
ok
[root@localhost ~]# [ $num1 -ge 2 ]&& echo good || echo ok $num1大于等于2,成立输出good,不成立输出ok
good
同样的,我们也可以用比较整数大小的方法来判断当前内存的大小。这里介绍一个命令“free -m”,表示以MB为单位输出内存信息。
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 3771 714 2387 17 668 2730
Swap: 3968 0 3968
[root@localhost ~]# free=$(free -m | grep "Mem" | awk '{print $4}') 将free -m 命令中Men一行中第四列的值赋给free
[root@localhost ~]# [ $free -gt 1024 ] && echo ${free}MB 如果$free大于1024MB,就输出这个值
2379MB
1.3 字符串比较
字符串通常用来检查用户输入、系统环境等是否满足条件,在交互式操作的shell脚本中,也可以用来判断用户输入的位置参数是否符合要求。常用的操作选项如下:
- = :第一个字符串与第二个字符串相同。
- != :第一个字符串与第二个字符串不相同,"!"表示取反。
- -z :检查字符串是否为空(Zero),对于未定义或赋空值的变量将视为空串;注意,空格为占一个字符。
[root@localhost ~]# echo $LANG
zh_CN.UTF-8
[root@localhost ~]# [ $LANG != US ]&& echo "Not CN" $LANG为系统环境变量,表示使用的语言,如果不等于US,就输出Not CN
Not CN
以一个简单的脚本演示
[root@localhost ~]# vi fugai.sh ##编辑脚本文件,脚本文件命名一定是.sh结尾
#!/bin/bash
read -p "是否覆盖文件:" ACK ##定义变量ACK,并输入提示信息
[ $ACK = yes ]&& echo "已覆盖" || echo "未覆盖" ##如果输入的提示信息是yes就输出"已覆盖",否则输出"未覆盖"
[root@localhost ~]# sh fugai.sh ##执行脚本文件
是否覆盖文件:yes
已覆盖
[root@localhost ~]# sh fugai.sh
是否覆盖文件:no
未覆盖
1.4 逻辑测试
逻辑测试指的是判断两个或多个条件之间的依赖关系。常见的逻辑测试操作如下:
- && :逻辑与,表示而且,只有前后两个条件都成立,整个测试的返回值才会为0,使用test命令时,可以改为“-a”。
- || :逻辑或,表示或者,只要前后的条件成立一个,整个测试的返回值就会为0,使用test命令时,可以改为“-o”。
- ! : 逻辑否,表示不,只有当指定条件不成立时,整个测试的返回值才为0。
“&&” 与"||“在之前已经演示过了,我演示一下”!"的用法,细细品味。
[root@localhost ~]# num1=10 将10赋给num1
[root@localhost ~]# [ ! $num1 -eq 10 ]&& echo ok 如果变量num1不等于10就输出ok
[root@localhost ~]# [ ! $num1 != 10 ]&& echo ok 如果变量num1等于10就输出ok
ok
二、 if语句
if语句是最为常见的流程控制方式,不仅在shell脚本,各种编程语言都离不开if语句,只是用法不同,思想是相似的。if语句比简单的逻辑测试要更清晰易懂。
2.1 单分支if语句
if语句中的分支指的是不同测试结果所对应的执行语句,可以是一条或是多条。对于单分支if语句,只有条件成立才会执行相应代码,否则不执行。
if 单分支语句用法
if 条件测试操作
then
相应命令代码
fi
流程图如下
2.2 双分支的if语句
双分支在单分支的基础上加入了条件不成立的情况。
if 双分支语句用法
if 条件测试操作
then
相应命令代码1
else
相应命令代码2
fi
流程图如下:
2.3 多分支if语句
由于if语句可以根据测试结果的成立与不成立分别执行不用的操作,所以可以嵌套使用,多次判断。
if 多分支语句用法
if 条件测试操作1
then
相应命令代码1
elif 条件测试操作2
then
相应命令代码2
else
相应命令代码3
fi
流程图如下:
三、 通过简单脚本实现if语句
3.1 单分支if语句应用
需求:想要挂载光盘镜像到一个目录下,但是不想查看这个目录是否存在,不存在就创建一个。
示例一:
[root@localhost ~]# vi chkmountdir.sh
#!/bin/bash
read -p "请输入你想要挂载的目录:" dir
if [ ! -d $dir ]
then
mkdir -p $dir
fi
需求:如果不是root用户执行这个脚本就会报错
示例二:
[root@localhost ~]# vi /opt/example2
#!/bin/bash
if [ "$USER" != "root" ]
then
echo "错误:非root用户,权限不足!"
exit 1 退出脚本,1表示返回的状态值
fi
3.2 双分支if语句应用
需求:检测目标主机的连通性
[root@localhost ~]# vi pinghost.sh
#!/bin/bash
read -p "请输入目标主机IP地址:" dizhi
ping -c 3 -i 0.2 -W 3 $dizhi &> /dev/null ##-c、-i、-W分别表示发送几个测试包、间隔几秒、超时几秒
if [ $? -eq 0 ]
then
echo "Host$1 is up."
else
echo "Host$1 is down."
fi
[root@localhost ~]# chmod +x pinghost.sh 提升权限,可执行权限
[root@localhost ~]# ./pinghost.sh
请输入目标主机IP地址:14.0.0.17
Host is down.
[root@localhost ~]# ./pinghost.sh
请输入目标主机IP地址:14.0.0.14
Host is up.
3.3 多分支if语句应用
需求:100米赛跑,跑进10s进决赛,通过性别将将进入决赛的人分为男子组和女子组。
[root@localhost ~]# vi fenzu.sh
#!/bin/bash
read -p "你跑了几秒:" time
if [ $time -le 10 ]
then
echo "恭喜你进入了决赛"
read -p "请说出你的性别:" sex
if [ $sex == "男" ]
then
echo "你进入了男子组"
elif [ $sex == "女" ]
then
echo "你进入了女子组"
else
echo "请重新输入"
fi
else
echo "很遗憾,你没有进入决赛"
fi
[root@localhost ~]# chmod +x fenzu.sh
[root@localhost ~]# ./fenzu.sh
你跑了几秒:10
恭喜你进入了决赛
请说出你的性别:男
你进入了男子组
[root@localhost ~]# ./fenzu.sh
你跑了几秒:1
恭喜你进入了决赛
请说出你的性别:女
你进入了女子组
[root@localhost ~]# ./fenzu.sh
你跑了几秒:11
很遗憾,你没有进入决赛
[root@localhost ~]# ./fenzu.sh
你跑了几秒:7
恭喜你进入了决赛
请说出你的性别:nan
请重新输入