一、条件测试
- Shell 环境根据命令执行后的返回状态值 " $? " 来判断是否执行成功,当返回值为0时表示成功,否则表示失败或异常(非0值)。
 - 使用专门的测试工具 test 命令,可以对特定条件进行测试,并根据返回值(值为0)来判断是否成立。
 
格式1:test  条件表达式
格式2:[  条件表达式  ]
注意[]空格,否则会失败
测试 是否成功使用 $?  返回值
[ 操作符 文件或目录 ]
help test 
test命令格式
test 条件表达式
或
[ 条件表达式 ]                  #条件表达式的两边都需要有空格,且此方法更为常用
或
[[ 条件表达式 ]]
 
1、文件测试
- 文件测试指的是根据给定的路径名称,判断对应的是文件还是目录,或者判断文件是否可读、可写、可执行等。
 
基本格式
[ 操作符 文件或目录 ] (注意两端要有空格) 
常用的选项:
| 选项 | 说明 | 
|---|---|
| -d | 测试是否为目录 | 
| -e | 测试目录或文件是否存在 | 
| -f | 测试是否为文件 | 
| -r | 测试当前用户是否有权限读取 | 
| -w | 测试当前用户是否有权限写入 | 
| -x | 测试当前用户是否有权限执行 | 
| -b | 测试是否为设备文件 | 
| -c | 测试是否为字符设备 | 
| -s | 测试存在且文件大小为空 | 
| -L | 测试是否为链接文件 | 
条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成
测试过程,实现评估布尔声明,以便用在条件性环境下进行执行
若真,则状态码变量 $? 返回0
若假,则状态码变量 $? 返回1 


比较两个文件时常用的选项
-nt:判断文件A是否比文件B新
-ot:判断文件A是否比文件B旧
-ef:判断两个文件是否为同一个文件,用来判断两个文件是否指向同一个inode。 
2、整数数值比较
整数值比较是指根据给定的两个整数值来判断第一个数与第二个数的关系,如是否大于、等于、小于第二个数。
基本格式:
[  整数1  -操作符  整数2  ] 公式 
| 格式 | 说明 | 
|---|---|
| -eq | 第一个数等于第二个数 | 
| -ne | 第一个数不等于第二个数 | 
| -gt | 第一个数大于第二个数 | 
| -lt | 第一个数小于第二数 | 
| -le | 第一个数小于或等于第二个数 | 
| -ge | 第一个数大于或等于第二个数 | 
[root@localhost test]# a=5
[root@localhost test]# b=10
[root@localhost test]# [ $a -eq $b ]
[root@localhost test]# echo $?
1
[root@localhost test]# [ $a -lt $b ]
[root@localhost test]# echo $?
0
[root@localhost test]# [ $a -le $b ]
[root@localhost test]# echo $?
0 

3、字符串比较
字符串比较通常用来检查用户输入、系统环境等是满足条件,在提供交互式操作的Shell脚本中,也可用来判断用户输入的位置参数是否符合要求。
格式
[ 字符串1  =    字符串2 ]            ##是否相同
[ 字符串1  !=    字符串2 ]           ##是否不相同
[ -z 字符串 ]                        ##是否为空
[ -n 字符串 ]                        ##字符是否存在 
常用的操作符
=:第一个字符串和第二个字符串相同
!=:第一个字符串与第二个字符串不相同,其中“!”符号表示取反
-z:字符串内容为空 
[root@localhost test]# str1=liu
[root@localhost test]# str2=yuan
[root@localhost test]# [ $str1 = $str2 ]               ##比较是否相同
[root@localhost test]# echo $?
1                                                      ##不相同
[root@localhost test]# [ $str1 != $str2 ]              ##比较是否不相同
[root@localhost test]# echo $?
0                                                      ##两者比较不相同,所以返回值为0,正确
 


4、逻辑运算(短路运算)
格式:
格式1:[  表达式1  ]  操作符  [  表达式2  ]  ... 
格式2:命令1  操作符  命令2  ...  
且 与 或
!  取反
且   &&
第一一个命令为真,才需要执行第二个命令
全真才为真,一假即为假
第一个命令假了,一定假了 
cmd1  && cmd2
全真才为真  一假即为假      
第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果 
第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2
或   ||
一真即为真,全假才为假
第一个命令为真,不需要执行第二个命令了,  一定为真了
第一个命令为假,需要执行第二个命令来看 整个式子的结果
cmd1 || cmd2 

常见的条件:
| -a或&& | 逻辑与,“而且”的意思全真才为真 | 
| -o或|| | 逻辑或,“或者”的意思一真即为真 | 
| ! | 逻辑否 | 



5、双中括号
[[ expression ]] 用法
== 左侧字符串是否和右侧的PATTERN相同
 注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
 注意: 此表达式用于[[  ]]中;扩展的正则表达式 

6、() {}
格式:
(CMD1;CMD2;...)和 {    CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行 
#()会开启子shell
[root@centos8 ~]#echo $BASHPID
1920
[root@centos8 ~]#( echo $BASHPID;sleep 100)
1979
[root@centos8 ~]#pstree -p
├─sshd(719)───sshd(1906)───sshd(1919)─┬─bash(1920)───bash(1979)───sleep(1980)
#{ } 不会开启子shell
[root@centos8 ~]#echo $BASHPID
1920
[root@centos8 ~]#{ echo $BASHPID; }
1920 
()表示执行过,直接显示结果;{}要执行操作,也显示结果;
()不需要结尾;{}需要;结尾;
()会开启子进程;{}不会开启子进程 
 
实操:
1.磁盘使用量






发邮件
vim mail.sh
#!/bin/bash
use=`df|grep /dev/sda|tr -s " "|cut -d " " -f5| tr -d %`
[ $use -ge 80 ] && echo "磁盘使用量不足" |mail -s warning 224----432@qq.com || echo "磁盘使用量足够"
bash mail.sh 
 

二、if语句
1、单分支if语句
单分支if语句:对于单分支的选择结构,只有在“条件成立”时才会执行相应的代码,否则不执行任何操作。
语法格式
if 条件测试操作
then
    命令序列
fi 



2、双分支if语句
对于双分支的选择结构,要求针对条件成立 条件不成立两种情况分别执行不同的操作。
语法格式
if 条件测试操作
then
    命令序列1
else
    命令序列2
fi 

3、多分支if语句
多分支结构能够根据多个互斥的条件分别执行不同的操作,实际上等同于嵌套使用的if语句。

三、case分支
 
case 语句可以使脚本程序的结构更加清晰、层次分明,常用于服务的启动、重启、停止的脚本,有的服务不提供这种控制脚本,需要用case语句编写。
 case 语句主要适用于以下情况: 某个变量存在多种取值,需要对其中的每一种取值分别执行不同的命令序列。这种情况与多分支的 if 语句非常相似,只不过 if 语句需要判断多个 不同的条件,而 case 语句只是判断一个变量的不同取值。
1、case语句结构
case 变量值 in 
模式一)
   命令序列
;;
模式二)
   命令序列 
;;
……
*)
   默认命令序列
esac 
2、case注意事项
- case行首必须为单词 “in”,每一模式必须以单个右括号")"结束。
 - 双分号 “;;” 表示命令序列的结束。
 - 模式字符串中,可以用方括号表示一个连续的范围,如"[0-9]",还可以用竖杠符号 “|”表示或,如“A|B”。
 - 最后的*)表示默认模式,其中的 *相当于通配符。
 - case行首必须为单词 “in”,每一模式必须以单个右括号")"结束。
 - 双分号 “;;” 表示命令序列的结束。
 - 模式字符串中,可以用方括号表示一个连续的范围,如"[0-9]",还可以用竖杠符号 “|”表示或,如“A|B”。
 - 最后的*)表示默认模式,其中的 *相当于通配符。
 


小实验:
石头剪刀布

鸡兔同笼


yes or no


判断服务是否开启

判断是否安装












