Shell中条件测试

Shell条件测试语句

Shell脚本就是各种命令、判断和循环语句的集合,如Linux命令、if条件语句、for循环语句等。即Shell脚本把含有逻辑运算的一段可执行代码写在了程序文件中。

Shell中,对指定的条件进行判断,执行条件测试表达式后通常会返回“真”或“假”,执行命令后的返回值为0表示真、非0表示假。

Shell编程中,通常使用test命令进行条件测试
语法形式为“test <测试表达式>”

注:利用test命令进行条件测试表达式时,test命令和“<测试表达式>”之间该有空格

文件测试

例1:使用test -f参数用于判断file是否存在且是否为普通文件,如果file存在且为普通文件,则输出true,否则输出false。

[root@localhost ~]# test -f file && echo true || echo false
false
​
[root@localhost ~]# touch file
[root@localhost ~]# test -f file && echo true || echo false
true

例2:语法格式:”[<测试表达式>]”,通过[ ]进行条件测试方法,与test命令用法相同

[root@localhost ~]#  [ -f file ] && echo 1 || echo 0
1

文件测试操作符如下:

操作符 含义
-d 测试是否为目录(Directory)
-a 测试目录或文件是否存在(Exist)
-f 测试是否为文件(File)
-r 测试当前用户是否可读(Read)
-w 测试当前用户是否可写(Write)
-x 测试当前用户是否可执行(Excute)

整数测试

整数测试用于数值之间的运算
语法格式:[ 整数 1 操作符 整数2 ]或test 整数1 操作符 整数2

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

例1:测试主机是否正常;使用while循环,设置i的初值为1,如果i小于等于5且$?执行结果为0.则主机为正常状态。

[root@localhost ~]# vim ping02.sh
#!/bin/bash
ip=192.168.10.100
i=1
while [ $i -le 5 ]
do
        ping -c1 $ip &>/dev/null
        if [ $? -eq 0 ];then
                echo "$ip is up"
        fi
        let i++
done

关系运算符:

符号 含义
== 等于(Equal)
!= 不等于(Not Equal)
> 大于(Greater Than)
< 小于(Lesser Than)
<= 小于或等于(Lesser or Than)
>= 大于或等于(Greater or Than)

例2:

[root@localhost ~]# ((1<2));echo $?
0
[root@localhost ~]# ((1==2));echo $?
1

字符串测试

字符串测试操作符用于比较字符串是否相同、测试字符串的长度是否为0.
书写表达式为[ 字符串1 = 字符串2 ]、[ 字符串1 != 字符串2 ]或[ -z 字符串 ]

字符串测试运算符

符号 含义
-z 判断字符串长度是否为0
-n 判断字符串长度是否非0
!= 判断两个字符串是否不相等
= 判断两个字符串是否相等

例:安装服务,判断变量user值是否为root,root则安装httpd,不是则提示权限不足。

#!/bin/bash
if [ $user != root ];then
        echo "权限不足"
        exit
fi
yum -y install httpd

逻辑运算符

在Shell条件测试中,使用逻辑运算符实现复杂的条件测试,用于操作两个变量。
逻辑运算符语法格式

[ 表达式1 ] 操作符 [ 表达式2 ]

命令1 操作符 命令2

逻辑运算符(-a和-o放在[]里面用,&&和||放在[]外面用)

运算符 含义
-a或&& 判断操作符两边均为真,结果为真,否则为假,”逻辑与”
-o或|| 判断操作符两边一边为真,结果为真,否则为假,”逻辑或“
! 判断操作符两边均为假,结果为真,否则为假,”逻辑否“

例:-a和&&的运算规则;两边都为真,输出1;否则为假,输出0

[root@localhost ~]# [ -f /etc/hosts -a -f /etc/services ] && echo 1 || echo 0
1
或
[root@localhost ~]# test -f /etc/hosts -a -f /etc/services && echo 1 || echo 0
1

if条件语句

流程控制语句有三类,分别为顺序语句、分支语句(条件语句)、循环语句。

if单分支

单分支语法格式:

if [ 条件表达式 ]
    then
        代码块
fi

或:

if [ 条件表达式 ];then
    代码块
fi

每个if条件语句都以if开头,并带有then,最后以fi结尾。表示为如果条件表达式的结果为真,则执行代码块中代码;如果条件表达式为假,不执行

例:if单分支语句判断文件/etc/hosts/是否存在,存在返回1。

[root@localhost ~]# vim ping03.sh
#!/bin/bash
if [ -f /etc/hosts ];then
        echo "1"
fi

if双分支

if条件语句的双分支结构语法格式为:

if [ 条件表达式 ]
    then
        代码块1
    else
        代码块2
fi

注:if双分支结构主体也可以把then和if放在一行用分号(;)隔开,表示如果条件表达式为真,执行代码块1,否则执行代码块2。

例:判断定义的名字是否为空。$name为空,则结果显示为yes;否则为no

[root@localhost ~]# vim name.sh
#!/bin/bash
name=wang
if [ -z "$name" ]
        then
                echo yes
        else
                echo no
fi

if多分支

if多分支结构语法格式

if [ 条件表达式1 ];then
    代码块1
elif [ 条件表达式2 ];then
    代码块2
elif [ 条件表达式3 ];then
    代码块3
else
    代码块4
fi

注:每个elif都要带有then;最后结尾else不带then。

例:if条件语句安装Apache。判断dns解析是否正常,返回值为0表示DNS正常,开始安装HTTP;否则判断网关是否正确,如果正常,则提示检查DNS,否则检查IP地址是否正确。

[root@localhost ~]# vim name.sh
#!/bin/bash
#install apache
#v1.0
gateway=192.168.10.1
​
ping -c1 www.baidu.com &>/dev/null
if [ $? -eq 0 ];then
        yum -y install httpd
        systemctl start httpd
        systemctl enable httpd
        firewall-cmd --permanent --add-service=http
        firewall-cmd --permanent --add-service=https
        firewall-cmd --reload
        sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config
        setenforce 0
elif ping -c1 $gateway &>/dev/null;then
        echo "check dns..."
else
        echo "check ip address!"
fi

if语句配置yum源实战脚本

根据当前操作系统的版本,配置不同的yum源脚本。

例:使用if多分支结构编写的根据系统版本配置yum源的脚本。判断系统版本后,执行相应代码块。

[root@localhost ~]# vim config_yum.sh
#!/bin/bash
#yum config
yum_server=192.168.10.1
os_version=cat /etc/redhat-release | awk '{print $4}' | awk -F"." '{print $1"."$2}'[ -d /etc/yum.repos.d ] || mkdir /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
if [ "$os_version" ="7.3" ];then
cat >/etc/yum.repos.d/CentOS 7us.repo <<-EOF [CentOS 7us] name=CentOS 7us baseurl=ftp:///$yum_server/CentOS 7us gpgcheck=0 EOF echo "7.3 yum configure…" elif [ "$os_version" = "6.8" ];then cat >/etc/yum.repos.d/CentOS 6u8.repo <<-EOF [CentOS 6u8] name=CentOS 6u8 baseurl=ftp://$yum_server/CentOS 6u8 gpgcheck=0 EOF elif [ ”$os_version“ = "5.9" ];then cat >/etc/yum.repos.d/CentOS 5u9.repo <<-EOF
[CentOS]
name=CentOS 5u9
baseurl=ftp://$yum_server/CentOS 5u9
gpgcheck=0
EOF
else
echo "error"
fi

case条件语句

case条件语句相当于多分支的if/elif/else条件语句。case语句常用于实现系统服务启动脚本等场景。

case语句固定语法格式:

case 变量值 in
    条件表达式1)
    代码块1
    ;;
    条件表达式2)
    代码块2
    ;;
    条件表达式3)
    代码块3
    ;;
    *)
    无匹配后代码块
esac

在case语句中,程序会获取case语句中的变量值,如果变量值满足条件,则执行代码块,执行到双分号(;;)停止。

条件表达式匹配

条件表达式 说明
* 任意字符
任意单个字符
[abc] a、b、c
[a-n] 从a到n的任一字符
| 多重选择

case条件语句案例

case删除用户判断

case语句结合read命令(读入用户输入的内容),与对应的变量名建立关联。如果用户输入正确则返回结果,输入错误则返回另外结果。

例:if条件语句删除用户脚本

[root@localhost ~]# vim del_user.sh
#!/bin/bash
#v1.0
read -p "Please input a username:" user
#用户输入后,赋值给user变量
id $user &>/dev/null
if [ $? -ne 0 ];then
        echo "no such a user: $user"
        exit 1
fi
read -p "Are you sure?[y/n]:" action
if [ "$action" = "y" -o "$action" = "Y" -o "$action" = "YES" -o "$action" = "yes" ];then
        userdel -r $user
        echo "$user is deleted"
fi
​
[root@localhost ~]# chmod a+x del_user.sh
[root@localhost ~]# ./del_user.sh 
Please input a username:user
Are you sure?[y/n]:y
user is deleted

使用case语句后

#!/bin/bash
#v1.0
read -p "Please input a username:" user
#用户输入后,赋值给user变量
id $user &>/dev/null
if [ $? -ne 0 ];then
        echo "no such a user: $user"
        exit 1
fi
read -p "Are you sure?[y/n]:" action
case "$case" in
y|Y|yes|YES)
        userdel -r $user
        echo "$user is deleted!"
        ;;
*)
        echo "error!"
esac

case实现系统工具箱的使用

系统工具箱就是查看系统情况,如内存大小、磁盘负载、CPU大小。

例:实现简单的系统工具箱脚本

[root@localhost ~]# vim system_manage.sh
#!/bin/bash
#v1.0
#system manage
menu() {
cat <<-EOF
        ##########################################
        #               h. help                 #
        #               f. disk partition       # 
        #               d. filesystem mount     #
        #               m. memory               #
        #               u. system load          #
        #               q. exit                 #
        ##########################################
EOF
}
menu
while true
do
        read -p "Please input [h for help]: " action
        clear
        case "$action" in
#输入h,打印菜单
        h)
                menu;;
#输入f,执行磁盘分区
        f)
                fdisk -l;;
#输入d,执行磁盘空间使用情况
        d)
                df -Th;;
#输入m,执行内存使用命令
        m)
                free -m;;
#输入u,获取主机运行时间和查询linux系统负载
        u)
                uptime;;
#输入q,退出
        q)
                break;;
#输入空值,不显示内容
        "")
                ;;
#除了以上情况,报错
        *)
                echo "error"
        esac
done
echo "finish"
​
[root@localhost ~]# chmod a+x system_manage.sh
[root@localhost ~]# ./system_manage.sh 
##########################################
#               h. help                 #
#               f. disk partition       # 
#               d. filesystem mount     #
#               m. memory               #
#               u. system load          #
#               q. exit                 #
##########################################
Please input [h for help]: f
​
Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b66c7
​
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200   419430399   208665600   8e  Linux LVM
​
Disk /dev/mapper/centos-root: 53.7 GB, 53687091200 bytes, 104857600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
​
​
Disk /dev/mapper/centos-swap: 4160 MB, 4160749568 bytes, 8126464 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
​
​
Disk /dev/mapper/centos-home: 155.8 GB, 155818393600 bytes, 304332800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
​
Please input [h for help]: 

case实现jumpserver

jumpserver是用python编写的开源跳板机/堡垒机系统,实现了跳板机的功能。基于SSH协议管理,客户端无需安装Agent。
所有SSH协议通过堡垒机来完成,功能有身份认证、控制访问、审计等功能。如下图:

例:使用case语句实现跳板机功能。以jane用户登录到跳板机后,在跳板机上使用case编写脚本跳转到三台后端服务器,分别为web1、web2、mysql1.执行用户登录到系统就会执行脚本。执行脚本的命令放在jane用户根目录.bashrc_profile文件中。

注:用户登录跳板机有两个方式认证:密码认证、密钥认证

例1:密码认证

[root@localhost ~]# vim jumpserver.sh
#!/bin/bash
#v1.0 jumpserver
web1=192.168.10.122
web2=192.168.10.123
mysql1=192.168.10.201
        cat <<-EOF
                +---------------------------------------+
                |               jumpserver              |
                |               1. web1                 |
                |               2. web2                 |
                |               3. mysql1               |
                +---------------------------------------+
        EOF
        read -p "Please input number:" num
        case "$num" in
        1)
                ssh jane@$web1
                ;;
        2)
                ssh jane@$web2
                ;;
        3)
                ssh jane@$mysql1
                ;;
        "")
                ;;
        *)
                echo "error"
        esac

例2:密钥认证

[root@localhost ~]# ssh-keygen
[root@localhost ~]# ssh-copy-id 192.168.10.122
[root@localhost ~]# ssh-copy-id 192.168.10.123
[root@localhost ~]# ssh-copy-id 192.168.10.201
[root@localhost ~]# vim jumpserver.sh
#!/usr/bin/bash
#v1.0 jumpserver
trap " " HUP INT OUIT TSIP  #Linux的捕捉信息,有这几个捕捉信号就什么都不做
web1=192.168.10.122
web2=192.168.10.123
mysql1=192.168.10.201
while
do
        cat <<-EOF
                +---------------------------------------+
                |               jumpserver              |
                |               1. web1                 |
                |               2. web2                 |
                |               3. mysql1               |
                +---------------------------------------+
        EOF
        echo -en "e[1;32minput number: e[0m"
        #显示绿色且加粗的文本input number‘
        #或 echo -en "33[1;32minput number: 33[0m"
        read num
        case "$num" in
        1)
                ssh jane@$web1
                ;;
        2)
                ssh jane@$web2
                ;;
        3)
                ssh jane@$mysql1
                ;;
        "")
                ;;
        *)
                echo "error"
        esac

case实现多版本PHP安装

PHP:重要中间件,PHP具有强大场景实现功能,主要用于服务端的脚本程序,可完成CGI程序能完成的工作,如收集表单数据、生成动态网页、发送或接收cookies。

例:实现多版本PHP安装

[root@localhost ~]# vim install_php.sh
#!/bin/bash
#install_php v1.0
install_php56() {
        echo "install php5.6..."
}
install_php70() {
        echo "install php7.0..."
}
install_php71() {
        echo "install php7.1..."
}
menu() {
        clear
        echo "################################"
        echo -e "	1 php-5.6"
        echo -e "	2 php-7.0"
        echo -e "	3 php-7.1"
        echo -e "	h help"
        echo -e "	q exit"
        echo "################################"
}
menu
while true
do
​
        read -p "version[1-3]: " version
        case "$version" in
        1)
                install_php56;;
        2)
                install_php70;;
        3)
                install_php71;;
        q)
                exit;;
        h)
                memu;;
        "")
                ;;
        *)
                echo "error";;
        esac
done
[root@localhost ~]# ./install_php.sh 
################################
        1 php-5.6
        2 php-7.0
        3 php-7.1
        h help
        q exit
################################
version[1-3]: 1
install php5.6...
version[1-3]: 2
install php7.0...
version[1-3]: 3
install php7.1...
version[1-3]: exit
error
version[1-3]: q
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容