要使Shell脚本程序具备必定的“智能”,面对的第一个问题就是如何区分不同的情况以确认履行何种操作。Shell环境依据指令履行后的回来状况值($?)来判别是否履行成功,当回来值为0时表示成功,否则(非0值)表示失利或反常。

运用专门的测验东西——test指令,能够对特定条件进行测验,并依据回来值来判别条件是否建立(回来值为0表示条件建立)。

运用test测验指令时,有以下两种方式:

格局一: test 条件表达式
​
格局二: [ 条件表达式 ]
​
#注意:每一项之间要有空格,格局二更常用
仿制代码

条件测验:判别某需求是否满足,需求由测验机制来完结,专用的测验表达式需求由测验指令辅佐完结。

测验进程,完结评估布尔声明,以便用在条件性环境下进行履行:

  • 若为真,则状况码变量 $? 回来0
  • 若为假,则状况码变量 $? 回来非0

1 条件测验句子

1.1文件测验

文件测验格局

格局一: test 操作符 表达式
​
格局二: [ 操作符 表达式 ] 
仿制代码

常用的文件测验操作符:

操作符 效果
-d 测验文件是否为目录文件(Directory)
-f 测验文件是否为普通文件(File)
-e 测验目录或文件是否存在(Exist)。主张运用-e,-a或许不精确。
-a 测验目录或文件是否存在(Exist)
-r 测验当时用户是否有权限读取(Read)
-w 测验当时用户是否有权限写入(Write)
-x 测验当时用户是否有权限履行(eXcute)
-L 测验是否为符号链接(软链接文件)
-nt 判别文件A是否比文件B新
-ot 判别文件A是否比文件B旧
-ef 判别两个文件是否为同一文件。可用于硬链接,主要判别两个文件是否指向同一个inode。

特点测验弥补:

操作符 效果
-s FILE 判别文件是否存在且非空
-t fd fd 指定文件描述符是否在某终端现已打开
-N FILE 文件自从上一次被读取之后是否被修改过
-O FILE 当时有效用户是否为文件属主
-G FILE 当时有效用户是否为文件属组

示例1:

[root@yuji ~]# test -d /etc/    //测验是否为目录
[root@yuji ~]# echo $?
0                 //状况码回来0,表示为真,是目录
[root@yuji ~]# [ -d /etc/ ]    //测验是否为目录
[root@yuji ~]# echo $?
0
[root@yuji ~]# test -f /etc/sysconfig   //测验是否为普通文件
[root@yuji ~]# echo $?
1                     //状况码回来1,表示为假,不是普通文件
[root@yuji ~]# [ -f /etc/sysconfig ]   //测验是否为普通文件
[root@yuji ~]# echo $?
1
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

示例2:

-e和-a都能够测验文件是否存在,但和 !(取反)连用时,-a或许不精确,主张运用-e

[root@yuji ~]# [ -e /etc/shadow ]   //测验文件是否存在
[root@yuji ~]# echo $?
0
[root@yuji ~]# [ -a /etc/shadow ]   //测验文件是否存在
[root@yuji ~]# echo $?
0
[root@yuji ~]# [ ! -a /etc/shadow ];echo $?   //测验文件是否不存在,判别成果有误
0
[root@yuji ~]# [ ! -e /etc/shadow ];echo $?   //测验文件是否不存在
1
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

示例3:

测验root用户对文件是否具有读、写、履行权限。

发现root用户的读取和写入权限,不受文件的根本权限操控;但履行权限受文件根本权限操控。

[root@yuji ~]# ll /etc/shadow
----------. 1 root root 3792 331 21:59 /etc/shadow
[root@yuji ~]# [ -r /etc/shadow ]   //测验root用户对文件是否具有读取权限
[root@yuji ~]# echo $?
0
[root@yuji ~]# [ -w /etc/shadow ]   //测验root用户对文件是否具有写入权限
[root@yuji ~]# echo $?
0
[root@yuji ~]# [ -x /etc/shadow ]   //测验root用户对文件是否具有履行权限
[root@yuji ~]# echo $?
1
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

示例4:

测验软链接时,目录称号后面不要加”/”,否则会被判别为目录文件。

[root@yuji /]# ls -dl /bin
lrwxrwxrwx. 1 root root 7 38 19:13 /bin -> usr/bin   //该文件为软链接文件
[root@yuji /]# [ -L /bin ]      //测验是否为软链接,是
[root@yuji /]# echo $?
0
[root@yuji /]# [ -L /bin/ ]     //测验是否为软链接,不是
[root@yuji /]# echo $?
1
[root@yuji /]# ls -dl /bin/
dr-xr-xr-x. 2 root root 49152 45 02:15 /bin/    //该文件为目录文件
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

1.2 整数测验

整数值比较:

[  整数变量1  操作符  整数变量2  ]
​
test 整数变量1  操作符  整数变量2
仿制代码

操作符:

操作符 意义
-eq 等于(Equal)
-ne 不等于(Not Equal)
-gt 大于(Greater Than)
-lt 小于(Lesser Than)
-le 小于或等于(Lesser or Equal)
-ge 大于或等于(Greater or Equal)

示例1:

[root@yuji /]# [ 2 -lt 3 ]    //测验2是否小于3
[root@yuji /]# echo $?
0
[root@yuji /]# a=5
[root@yuji /]# b=6
[root@yuji /]# [ $a -eq $b ]   //测验变量a是否等于变量b
[root@yuji /]# echo $?
1
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

示例2:

查询当时目录下的文件数量是否大于10,假如大于,则进行提示。

[root@yuji ~]# ls | wc -l
40
[root@yuji ~]# test `ls |wc -l` -gt 10 && echo "文件数量大于10"
文件数量大于10
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

1.3 字符串测验

常用的测验操作符

  • =:字符串内容相同
  • !=:字符串内容不同,! 号表示相反的意思
  • -z:字符串内容为空
  • -n:字符是否存在

字符串比较,常用的四种格局:

[ "字符串1" = "字符串2"  ]  //测验字符串1和字符串2的内容是否相同
[ "字符串1" != "字符串2”  ]  //测验字符串1和字符串2的内容是否不同
[ -z "字符串" ]   //测验字符串是否为空,或许指定的变量是否为空值。(测验字符串的长度是否为零)
[ -n "字符串" ]   //测验字符串是否存在,即是否不为空。(测验字符串的长度是否非零)
仿制代码

示例1:

[root@yuji ~]# str1=aa
[root@yuji ~]# str2=bb
[root@yuji ~]# [ $str1 = $str2 ];echo $?   //测验变量1和变量2的值是否相同
1
[root@yuji ~]# [ $USER = root ];echo $?   //测验当时用户是否为root
0
[root@yuji ~]# [ $USER != root ];echo $?   //测验当时用户是否不为root
1
[root@yuji ~]# [ -z $HOME ];echo $?     //测验变量HOME是否为空值
1
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

示例2:

运用-z或-n测验变量时,变量需求加引号,防止有歧义而导致判别成果有误。

[root@yuji ~]# empty=        //设置一个空值变量
[root@yuji ~]# echo $empty
​
[root@yuji ~]# [ -z $empty ]     //测验变量是否为空值,为空
[root@yuji ~]# echo $?
0
[root@yuji ~]# [ -n $empty ]     //变量没加引号,导致判别成果有误
[root@yuji ~]# echo $?
0
[root@yuji ~]# [ -n "$empty" ]    //加了引号,判别成果正确
[root@yuji ~]# echo $?
1
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

1.4 逻辑测验(短路运算)

逻辑测验用于连接多个测验条件,并回来整个表达式的值。 逻辑测验主要有”逻辑与”,”逻辑或”,”逻辑否”三种。

逻辑测验两种格局:

格局一:[  表达式1  ]  逻辑运算符  [  表达式2  ] ...
#例:[表达式1] && [表达式2]  等同于  [表达式1 -a 表达式2]  等同于  [[表达式1 && 表达式2]]
#例:[表达式1] || [表达式2]  等同于  [表达式1 -o 表达式2]  等同于  [[表达式1 || 表达式2]]
​
格局二:指令1  逻辑运算符  指令2  ... 
仿制代码

逻辑运算符:

  • -a或&& :逻辑与,“而且”的意思,全真才为真。
  • -o或|| :逻辑或,“或许”的意思,一真即为真。
  • ! :逻辑否。

shell编程之条件语句(条件测试、if语句、case语句)

1)短路与 &&

CMD1 && CMD2
全真才为真,一假即为假。   
第一个CMD1成果为真 ,第二个CMD2必须要参与运算,才能得到最终的成果。
第一个CMD1成果为假 ,总的成果必定为假,因而不需求履行CMD2。
同时满足指令1 和指令2 的要求,才会回来正确。
仿制代码

2)短路或 ||

CMD1 || CMD2
一真即为真
第一个CMD1成果为真,总的成果必定为真,因而不需求履行CMD2。
第一个CMD1成果为假,第二个CMD2必须要参与运算,才能得到最终的成果。
仿制代码

1.4.1 二元运算符

示例1:

[root@yuji ~]# [ 1 -lt 2 ] && [ 3 -eq 4 ]   //测验1是否小于2,同时3是否等于4
[root@yuji ~]# echo $?
1                       //成果为假
[root@yuji ~]# [ 1 -lt 2 ] || [ 3 -eq 4 ]   //测验1是否小于2,或许3是否等于4
[root@yuji ~]# echo $?
0                       //成果为真
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

示例2:

[表达式1] && [表达式2] 等同于 [表达式1 -a 表达式2] 等同于 [[表达式1 && 表达式2]]

[root@localhost ~]# a=5
[root@localhost ~]# [ $a -ne 1 ]&&[ $a != 2 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $a -ne 1 -a  $a != 2 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ $a -ne 1 &&  $a != 2 ]]
[root@localhost ~]# echo $?
0
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

1.4.2 三元运算符

1、java,C言语

  • 条件表达式?a:b
  • 当条件表达式为真时,取a值;当条件表达式为假时,取b值。

2、shell

  • [ 表达式 ] && a || b
  • 当表达式为真时,取a值;当表达式为假时,取b值。
[ 表达式 ]  && a      //相当于 if句子单分支结构[ 表达式 ]  && a || b    //相当于 if句子双分支结构[ 表达式 ]  || b      //相当于 if [表达式];else
仿制代码

事例运用:检查指定主机是否在线。

1)方法一:运用三元运算符

[root@yuji ~]# vim ping001.sh       //运用三元运算符写脚本
#!/bin/bash
ping -c 3 -i 0.5 -w 3 $1 &>/dev/null && echo "$1 is up" || echo "$1 is down"
​
[root@yuji ~]# bash ping001.sh 192.168.72.10      //履行脚本测验主机是否在线
192.168.72.10 is up
[root@yuji ~]# bash ping001.sh 192.168.72.22
192.168.72.22 is down
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

shell编程之条件语句(条件测试、if语句、case语句)

2)方法二:运用 if句子双分支结构

[root@yuji ~]# vim ping002.sh               //运用if句子写脚本
#!/bin/bash
ping -c 3 -i 0.5 -w 3 $1 &>/dev/null 
​
if [ $? -eq 0 ]
then
  echo "$1 is online" 
else  
  echo "$1 is offline"
fi
​
[root@yuji ~]# bash ping002.sh 192.168.72.10      //履行脚本测验主机是否在线
192.168.72.10 is online
[root@yuji ~]# bash ping002.sh 192.168.72.22
192.168.72.22 is offline
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

shell编程之条件语句(条件测试、if语句、case语句)

小贴士:

ping指令:

  • -c,发送包的个数。
  • -i,发送的间隔时刻。
  • -w(小写),多少秒后中止ping操作。
  • -W(大写),以毫秒为单位设置ping的超时时刻 。

2 if 句子

2.1 if 单分支结构

单分支句子格局:

if  判别条件
​
then  条件建立的分支代码
​
fi             //条件不建立直接结束
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

事例运用:

判别已用磁盘空间是否大于80%,假如是就报警提示。

# 运用df指令能够检查磁盘空间运用和剩余情况
[root@yuji ~]# df
文件系统          1K-块   已用   可用 已用% 挂载点
/dev/mapper/centos-root 17811456 5063256 12748200  29% /
devtmpfs         483928    0  483928  0% /dev
tmpfs           499848    0  499848  0% /dev/shm
tmpfs           499848  7264  492584  2% /run
tmpfs           499848    0  499848  0% /sys/fs/cgroup
/dev/sda1        1038336 182372  855964  18% /boot
tmpfs           99972   12  99960  1% /run/user/42
tmpfs           99972    0  99972  0% /run/user/0
[root@yuji ~]# df |grep /dev/mapper/centos-root
/dev/mapper/centos-root 17811456 5063288 12748168  29% /
[root@yuji ~]# df |grep /dev/mapper/centos-root |awk '{print $5}'
29%
[root@yuji ~]# df |grep /dev/mapper/centos-root |awk '{print $5}' |awk -F '%' '{print $1}'
29
​
​
# 编写脚本
[root@yuji ~]# vim diskused.sh
#!/bin/bash
# 判别已用磁盘空间是否大于80%,假如是则报警提示。
​
used=$(df |grep /dev/mapper/centos-root |awk '{print $5}' |awk -F '%' '{print $1}')
​
if [ $used -gt 80 ]
then
  echo "警告!当时 /目录的磁盘运用率为 ${used}%"
fi
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

shell编程之条件语句(条件测试、if语句、case语句)

测验脚本:

能够先将判别条件修改为大于20%,测验脚本是否收效。

shell编程之条件语句(条件测试、if语句、case语句)

2.2 if 双分支结构

双分支句子格局:

if 判别条件
then
    条件建立的分支代码
else
    条件不建立的分支代码
fi
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

事例运用:

检测80端口是否在监听,假如是,则提示”网站服务已在运转“;假如否,则发动httpd服务。

# 写脚本
[root@yuji ~]# vim httpd80.sh
#!/bin/bash
# 检测80端口是否在监听,假如是,则提示”网站服务已在运转“;假如否,则发动httpd服务。
​
netstat -ntap | grep :80 &> /dev/nullif [ $? -eq 0 ]
then
  echo "网站服务已在运转"
else
  if rpm -q httpd &> /dev/null
  then
    echo "正在发动httpd服务"
     systemctl start httpd
  else
    echo "正在装置并发动httpd服务"
     yum install httpd -y &> /dev/null
         systemctl start httpd &> /dev/null
    fi
 fi
    
# 履行脚本
[root@yuji ~]# bash httpd80.sh    //检测到未装置httpd服务,自动装置
正在装置并发动httpd服务
[root@yuji ~]# rpm -q httpd      //检查软件包是否装置,已装置
httpd-2.4.6-97.el7.centos.5.x86_64
[root@yuji ~]# bash httpd80.sh    //httpd服务已运转
网站服务已在运转
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

shell编程之条件语句(条件测试、if语句、case语句)

2.3 if 多分支结构

多分支句子格局:

if 判别条件1
then
    条件1为真的分支代码
​
elif 判别条件2
then
    条件2为真的分支代码
​
elif 判别条件3
then
    条件3为真的分支代码
​
...
else
    以上条件都为假的分支代码
​
fi
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

事例运用:

检查当时时刻点,依据不同时刻规模输出不同问候语。

  • 6点-10点,输出早上好;
  • 11点-13点,输出中午好;
  • 14点-18点,输出下午好;
  • 19点-22点, 输出晚上好;
  • 其他时刻,休息时刻。
[root@yuji ~]# date      //检查当时详细时刻
2022年 04月 10日 星期日 15:01:25 CST
[root@yuji ~]# date +%H    //检查当时时刻在哪个小时(规模0-23)
15
[root@yuji ~]# vim date.sh   //写脚本
#!/bin/bash
# 检查当时时刻点,依据不同时刻规模输出不同问候语。
​
h=$(date +%H)
​
if [ $h -ge 6 -a $h -le 10 ]
then
  echo "早上好"
elif [ $h -ge 11 -a $h -le 13 ]
then
  echo "中午好"
elif [ $h -ge 14 -a $h -le 18 ]
then
  echo "下午好"
elif [ $h -ge 19 -a $h -le 22 ]
then
  echo "晚上好"
else
  echo "休息时刻"
fi
​
[root@yuji ~]# bash date.sh    //履行脚本
下午好
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

shell编程之条件语句(条件测试、if语句、case语句)

3 case句子

格局:

case 变量引用 in
模式1)
    指令分支1
    ;;
模式2)
    指令分支2
    ;;
...
*)
    默认指令分支
esac
仿制代码

注意事项:

case支持glob风格的通配符:
* :恣意长度恣意字符
? :恣意单个字符
[0-9] :指定规模内的恣意单个字符
| :“或许”的意思,如: a|b
仿制代码

事例运用:

提示用户输入分数(0-100),判别分数规模,分出优异、杰出、及格、不及格四档。假如用户输入的分数值不在0-100之间,则提示从头输入。

# 写脚本
[root@localhost ~]# vim gradediv.sh
#!/bin/bash
#提示用户输入分数(0-100),判别分数规模,分出优异、杰出、及格、不及格四档。
#假如用户输入的分数值不在0-100之间,则提示从头输入。
​
read -p "请输入你的分数(0-100):" grade
​
case $grade in
100)
  echo "你很优异"
   ;;
[89][0-9])
  echo "你表现杰出"
   ;;
[67][0-9])
  echo "你及格了"
   ;;
[0-9]|[1-5][0-9])
  echo "你不及格"
   ;;
*)
  echo "输入有误,请从头输入0-100"
  bash $0
esac
​
# 履行脚本
[root@localhost ~]# bash gradediv.sh
请输入你的分数(0-100):0
你不及格
[root@localhost ~]# bash gradediv.sh
请输入你的分数(0-100):33
你不及格
[root@localhost ~]# bash gradediv.sh
请输入你的分数(0-100):67
你及格了
[root@localhost ~]# bash gradediv.sh
请输入你的分数(0-100):92
你表现杰出
[root@localhost ~]# bash gradediv.sh
请输入你的分数(0-100):100
你很优异
[root@localhost ~]# bash gradediv.sh
请输入你的分数(0-100):300
输入有误,请从头输入0-100
请输入你的分数(0-100):85
你表现杰出
仿制代码

shell编程之条件语句(条件测试、if语句、case语句)

shell编程之条件语句(条件测试、if语句、case语句)

4 易错总结

  1. 测验文件是否存在时,主张运用-e。如:[ -e /etc/passwd ]
  2. root用户的读取和写入权限,不受文件的根本权限操控;但履行权限受文件根本权限操控。
  3. 测验软链接时,目录称号后面不要加”/”,否则会被判别为目录文件。如:[ -L /bin ]
  4. 运用-z或-n测验变量时,变量需求加引号,防止有歧义而导致判别成果有误。如:[ -n “$empty” ]