Shell条件测试
结构化命令概念
Shell按照命令在脚本中出现的顺序依次进行处理。对顺序操作来说,这已经足够了,因为在这种操作环境下,你想要的就是所有的命令按照正确的顺序执行。
许多程序要求对shell脚本中的命令施加一些逻辑流程控制。有一类命令会根据条件使脚本跳过某些命令。这样的命令通常称为结构化命令(structured command)
常见的条件测试命令: if-then语句 、 case语句 、 for语句 、 while语句
if条件语句
语法结构
if单分支语句
if条件语句通常由以下三个关键字组成:
- if:用于指定要测试的条件
- then:用于指定如果条件为true时要执行的指令
- else:用于指定如果条件为false时要执行的指令
if condition
then
command1
command2
...
commandN
fi
在其他编程语言中,if语句之后的对象是一个等式,这个等式的求值结果为TRUE或FALSE。但bash shell的if语句并不是这么做的。bash shell的if语句会运行if后面的那个命令。如果该命令的退出状态码是0(该命令成功运行),位于then部分的命令就会被执行。如果该命令的退出状态码是其他值,then部分的命令就不会被执行,bash shell会继续执行脚本中的下一个命令。fi语句用来表示if-then语句到此结束。
创建脚本test.sh、编辑以下内容:
#!/bin/bash
# 测试的条件为`pwd`命令,根据命令的返回值进行跳转
if pwd
then
echo "[提示] pwd 命令执行成功,已进入对应目录。"
fi
运行脚本:
[root@host1 ~]# bash test.sh
/home/centos
[提示] pwd 命令执行成功,已进入对应目录。
常见的退出状态码:
if-then 语句的另一种形式
if command; then
commands
fi
if-then-else 双分支语句
当if语句中的命令返回退出状态码0时,then部分中的命令会被执行,这跟普通的if-then
语句一样。当if语句中的命令返回非零退出状态码时,bash shell会执行else部分中的命令。
在test.sh文件的基础上添加else语句
#!/bin/bash
# 待测试的用户名为ubuntu
testuser=ubuntu
# 此时grep命令没有找到ubuntu字符,if语句跳转到else分支
if grep $testuser /etc/passwd
then
echo "[成功] 用户 $testuser 存在于系统中。"
# 同时显示家目录下以.b开头的隐藏文件
ls -a /home/$testuser/.b*
else
echo "[失败] 用户 $testuser 在系统中不存在。"
fi
运行脚本:
[root@host1 ~]# bash test.sh
[失败] 用户 ubuntu 在系统中不存在。
if-then-elif-else 多分支语句
if condition1
then
command1
...
elif condition2
then
command1
...
else
command1
...
fi
作业1:先在
/home/目录下创建名为ubuntu的目录,然后参考修改上一个脚本添加elif分支检测当用户ubuntu不存在,但是存在同名的ubuntu目录时在改目录中创建一个空文件tmp,提交执行结果。
条件判断
test命令如果test命令中列出的条件成立,test命令就会退出并返回退出状态码0。这样if-then语句就与其他编程语言中的if-then语句以类似的方式工作了。如果条件不成立,test命令就会退出并返回非零的退出状态码,这使得if-then语句不会再被执行。
test命令格式
if test condition then commands fibash shell提供了另一种条件测试方法,无需在if-then语句中声明test命令。
if [ condition ] then commands fi创建脚本test.sh、编辑以下内容:
#!/bin/bash testuser=centos # 当变量 testuser 不为空时执行 then 语句的内容 if [ $testuser ] then echo "变量 testuser 的值当前为: $testuser" fi运行脚本:
[root@host1 ~]# bash test.sh 变量 testuser 的值当前为: centos
方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。
一共可以总结为三类条件:
文件比较
这些测试条件使你能够在shell脚本中检查文件系统中的文件。它们经常出现在需要进行文件访问的脚本中,文件比较的操作符如下:
创建脚本test.sh、编辑以下内容:
#!/bin/bash dir=/home/centos # 根据 -d 判断 dir 是否存在且是一个目录 if [ -d $dir ] then echo "[状态] 目录 $dir 确实存在。" cd $dir ls fi运行脚本:
[root@host1 ~]# bash test.sh [状态] 目录 /home/centos 确实存在。 log.230616 test.sh字符串比较
创建脚本test.sh、编辑以下内容:
#!/bin/bash testuser=centos # 通过比较运算符等号 = 比较两个字符串,等式成立则表达式结果为真 if [ $USER = $testuser ] then echo "[你好] 欢迎回来,$testuser!" fi运行脚本:
[root@host1 ~]# bash test.sh [你好] 欢迎回来,centos!- 大于号和小于号必须转义,否则 shell 会把它们当作重定向符号,把字符串值当作文件名
创建脚本 test.sh、编辑以下内容:
#!/bin/bash var1=temp var2=tmp # 在条件比较时直接使用大于号 > 不能表示大于的含义,需要使用 \> 来表示“大于” if [ $var1 \> $var2 ] then echo "[结果] 字符串 $var1 大于 $var2" else echo "[结果] 字符串 $var1 不大于 $var2" fi运行脚本:
[root@host1 ~]# bash test.sh数值比较
数值条件测试可以用在数字和变量上。

复合条件测试
&&和||用法[ condition1 ] && [ condition2 ] [ condition1 ] || [ condition2 ]- 第一种布尔运算使用AND布尔运算符来组合两个条件。要让then部分的命令执行,两个条件都必须满足。
- 第二种布尔运算使用OR布尔运算符来组合两个条件。如果任意条件为TRUE,then部分的命令就会执行。
作业2:参考以上字符串比较、复合条件测试的内容,检查当前系统是否存在名为
centos的用户同时/home目录下是否存在名为centos的目录(文件比较),如果都成立则在该目录下创建一个空文件,运行脚本查看结果。
case命令
在shell编程中,case语句是一种多分支条件语句,用于测试变量或表达式是否与某些模式匹配,并执行相应的命令。
case语句通常用于替代if-then-else语句,特别是在需要测试一个变量或表达式是否匹配多个模式的情况下。case语句的语法结构如下:
case expression in
pattern1)
command1
;;
pattern2)
command2
;;
pattern3)
command3
;;
*)
default_command
;;
esac
其中,expression是要测试的变量或表达式,pattern1、pattern2、pattern3等是匹配模式,command1、command2、command3等是匹配模式成立时要执行的命令,;;表示命令结束,*)表示如果所有模式都不匹配时要执行的默认命令。
创建脚本test.sh、编辑以下内容:
#!/bin/bash
fruit="apple"
case $fruit in
apple)
echo "[匹配] 这是一个苹果。"
;;
banana)
echo "[匹配] 这是一个香蕉。"
;;
# * 用来匹配之前所有模式都匹配不到的情况
*)
echo "[提示] 既不是苹果也不是香蕉。"
;;
esac
运行脚本:
[root@host1 ~]# bash test.sh
[匹配] 这是一个苹果。
作业3:编写程序实现以下要求
- 使用
read要求用户输入一个数字。- 使用
if判断该数字是否在0-9之间,如果不满足则停止脚本。- 然后使用
case语句输出对应数字0-2的英文,对于其他数字输出一个提示“该数字在4-9之间”。