zoukankan      html  css  js  c++  java
  • 03Shell条件测试

    条件测试

    Shell 条件测试

    格式 1: test 条件表达式
    格式 2: [ 条件表达式 ]
    格式 3: [[ 条件表达式 ]]  
    

    具体参数说明可以通过 man test 进行查看

    文件测试

    [ 操作符 文件或目录 ]
    

    [ -b FILE ]

    FILE存在而且是块设备文件,则为True
    

    [ -c FILE ]

    FILE存在而且是字符文件,则为True
    

    [ -d FILE ]

    FILE存在而且是目录,则为True
    

    [ -e FILE ]

    FILE存在,则为True
    

    [ -f FILE ]

    FILE存在而且是普通文件,则为True
    

    [ -g FILE ]

    FILE存在而且设置了SGID位,则为True
    

    [ -k FILE ]

    FILE存在而且设置了粘着位,则为True
    

    [ -L FILE ]

    FILE存在而且是符号链接文件,则为True
    
    -L 相当于 -h
    

    [ -p FILE ]

    FILE存在而且是管道文件,则为True
    

    [ -r FILE ]

    FILE存在而且【当前用户】对该文件有读权限,则为True
    

    [ -w FILE ]

    FILE存在而且【当前用户】对该文件有写权限,则为True
    

    [ -x FILE ]

    FILE存在而且【当前用户】对该文件有执行权限,则为True
    

    [ -u FILE ]

    FILE存在而且设置了SUID位,则为True
    

    [ FILE1 -nt FILE2 ]

    FILE1比FILE2新(指的是修改时间modification date),则为True
    

    [ FILE1 -ot FILE2 ]

    FILE1比FILE2旧(指的是修改时间modification date),则为True
    

    数值比较

    [ 整数 1 操作符 整数 2 ]    
    

    [ num1 -eq num2 ]

    num1 等于num2,则为True
    

    [ num1 -ne num2 ]

    num1 不等于num2,则为True
    

    [ num1 -lt num2 ]

    num1 小于num2,则为True
    

    [ num1 -le num2 ]

    num1 小于或者等于num2,则为True
    

    [ num1 -gt num2 ]

    num1 大于num2,则为True
    

    [ num1 -ge num2 ]

    num1 大于或者等于num2,则为True
    

    C 语言风格的数值比较

    # 小于
    [root@yangs ~]# ((1<2));echo $?
    0
    # 等于
    [root@yangs ~]# ((1==2));echo $?
    1
    # 大于
    [root@yangs ~]# ((1>2));echo $?
    1
    # 大于等于
    [root@yangs ~]# ((1>=2));echo $?
    1
    # 小于等于
    [root@yangs ~]# ((1<=2));echo $?
    0
    # 不等于
    [root@yangs ~]# ((1!=2));echo $?
    0
    # 命令执行结果是否大于0
    [root@yangs ~]# ((`id -u`>0));echo $?
    1
    # UID是否等于0
    [root@yangs ~]# (($UID==0));echo $?
    0
    

    字符串比较

    注意 双引号的使用

    [ -z string ]

    字符串string长度为零,则为True
    

    [ -n string ]

    字符串string长度非零,则为True
    

    [ string1 = string2 ]

     string1与 string2相同,则为真
    

    [ string1 != string2 ]

    string1与 string2不同,则为真
    

    测试条件之间的逻辑关系

    条件测试中的测试条件之间的逻辑关系

    ( EXPRESSION )

    判断当前条件EXPRESSION是否为真

    逻辑与

    EXPRESSION1 -a EXPRESSION2
    

    判断条件EXPRESSION1和EXPRESSION2是否同时为真

    逻辑或

    EXPRESSION1 -o EXPRESSION2
    

    判断条件EXPRESSION1和EXPRESSION2是否其中一个为真:

    EXPRESSION1为真,则不判断EXPRESSION2

    EXPRESSION1为假,则判断EXPRESSION2的真假

    逻辑非

    ! EXPRESSION
    

    判断当前条件EXPRESSION是否为假

    示例

    数值比较

    例1

    磁盘使用率检查

    # 编写脚本
    [root@hadoop04 shell]# vim disk_use.sh
    #!/usr/bin/bash
    
    red_col="e[31m"
    green_col="e[32m"
    reset_col="e[0m"
    
    
    disk_use=`df -Th | grep "/$" | awk '{print $(NF-1)}' | awk -F "%" '{print $1}'`
    
    if [ ${disk_use} -ge 90 ];then
    
      echo -e "${red_col}disk use is dangerous,current value is ${disk_use}%${reset_col}"
    
    else
    
      echo -e "${green_col}disk use is healthy,current value is ${disk_use}%${reset_col}"
    fi
    
    # 执行脚本
    [root@hadoop04 shell]# bash disk_use.sh
    disk use is healthy,current value is 14%
    

    例2

    磁盘使用率检查,发送邮件通知(正常或者异常都发送)

    # 编写脚本
    [root@hadoop04 shell]# vim disk_use_mail.sh
    #!/usr/bin/bash
    
    disk_use=`df -Th | grep "/$" | awk '{print $(NF-1)}' | awk -F "%" '{print $1}'`
    
    if [ ${disk_use} -ge 90 ];then
    
      echo "`date '+%F %H:%M:%S'` disk use is dangerous,current value is ${disk_use}%" | mail -s "disk use is too high" alice
    
    else
    
      echo "`date '+%F %H:%M:%S'` disk use is healthy,current value is ${disk_use}%" | mail -s "disk use is healthy" alice
    fi
    # 执行脚本
    [root@hadoop04 shell]# bash disk_use_mail.sh 
    
    
    # 切换到alice用户
    [root@hadoop04 ~]# su - alice
    # 查收邮件
    [alice@hadoop04 ~]$ mail
    Heirloom Mail version 12.5 7/5/10.  Type ? for help.
    "/var/spool/mail/alice": 1 message
    >   1 root                  Sun Dec  8 11:21  19/681   "disk use is healthy"
    # 输入想要查看的邮件编号,此处为1
    & 1
    Message  1:
    From root@hadoop04.localdomain  Sun Dec  8 11:21:17 2019
    Return-Path: <root@hadoop04.localdomain>
    X-Original-To: alice
    Delivered-To: alice@hadoop04.localdomain
    Date: Sun, 08 Dec 2019 11:21:17 +0800
    To: alice@hadoop04.localdomain
    Subject: disk use is healthy
    User-Agent: Heirloom mailx 12.5 7/5/10
    Content-Type: text/plain; charset=us-ascii
    From: root@hadoop04.localdomain (root)
    Status: RO
    
    2019-12-08 11:21:17 disk use is healthy,current value is 14%
    # 退出查看
    & exit
    

    例3

    内存使用率检查,发送邮件告警

    [root@hadoop04 shell]# vim mem_usage_mail.sh
    #!/usr/bin/bash
    
    # 获取内存使用情况
    
    mem_used=`free -m | grep Mem | awk '{print $3}'`
    mem_total=`free -m | grep Mem | awk '{print $2}'`
    mem_percent=$((100*mem_used/mem_total))
    
    warn_file=/tmp/mem_warn.txt
    health_file=/tmp/mem_health.txt
    
    # 删除告警文件,以免对告警造成误导
    
    rm -rf ${warn_file}
    
    # 判断内存使用情况
    
    if [ ${mem_percent} -ge 80 ];then
      echo "[warning] `date +%F %H:%M:%S` memory: ${mem_percent}%" > ${warn_file}
    else
      echo "[healthy] `date +%F %H:%M:%S` memory: ${mem_percent}%" >> ${health_file}
    fi
    
    # 告警文件存在,就发邮件告警;发送完成后,删除告警文件
    
    if [ -f ${warn_file} ];then
      mail -s "mem warn ..." alice < ${warn_file}
      rm -rf ${warn_file}
    fi
    

    字符串比较

    建议字符串使用双引号引起来

    判断字符串是否相等
    # username变量不存在,直接判断会出现语法错误
    [root@hadoop04 shell]# [ $username = "root" ]
    -bash: [: =: unary operator expected
    [root@hadoop04 shell]# echo $?
    2
    [root@hadoop04 shell]# [ $username != "root" ];echo $?
    -bash: [: !=: unary operator expected
    2
    
    
    # 使用双引号,可以规避上面的语法错误
    [root@hadoop04 shell]# [ "$username" = "root" ]
    [root@hadoop04 shell]# echo $?
    1
    [root@hadoop04 shell]# [ "$username" != "root" ];echo $?
    0
    
    判断字符串长度

    小结:变量为空 或 未定义,长度都为 0

    # 定义一个var,不赋值即变量值的长度为0
    [root@hadoop04 shell]# var=
    [root@hadoop04 shell]# echo ${#var}
    0
    #判断长度是否等于0时,存在问题,都可以判断为True
    [root@hadoop04 shell]# [ -z $var ];echo $?
    0
    [root@hadoop04 shell]# [ -n $var ];echo $?
    0
    
    # 使用双引号,可以规避上面的判断问题
    [root@hadoop04 shell]# [ -z "$var" ];echo $?
    0
    [root@hadoop04 shell]# [ -n "$var" ];echo $?
    1
    

    应用案例

    输入数量和用户前缀,创建用户的脚本

    [root@hadoop04 shell]# vim useradd01.sh
    #!/usr/bin/bash
    ##########################################
    # useradd                                #
    # v1.0 by ElegantSmile 8/12/2019         #
    ##########################################
    
    read -p "please input number: " num
    read -p "please input prefix: " prefix
    
    for i in `seq ${num}`
    do
      username=${prefix}${i}
      useradd ${username}
      echo "123" | passwd -stdin ${username} &> /dev/null
      #filename=${prefix}${i}
      #touch ${filename}
      if [ $? -eq 0 ];then
        echo "${username} is created" 
      fi
    
    done
    

    升级版:增加对数量和用户前缀的判断,非法输入将直接退出脚本

    [root@hadoop04 shell]# vim useradd02.sh
    #!/usr/bin/bash
    ##########################################
    # useradd                                #
    # v1.0 by ElegantSmile 8/12/2019         #
    ##########################################
    
    read -p "please input number: " num
    
    # 判断输入的num是否为数字
    if [[ ! "${num}"  =~ ^[0-9]+$ ]];then
      echo "error number!"
      exit
    fi
    
    
    read -p "please input prefix: " prefix
    
    # 判断是否输入prefix
    if [ -z "${prefix}" ];then
      echo "error prefix"
      exit
    fi
    
    
    for i in `seq ${num}`
    do
      username=${prefix}${i}
      useradd ${username}
      echo "123" | passwd -stdin ${username} &> /dev/null
      #filename=${prefix}${i}
      #touch ${filename}
      if [ $? -eq 0 ];then
        echo "${username} is created" 
      fi
    
    done
    

    再升级版:增加循环判断,非法输入将进入循环,直到输入正确的变量

    [root@hadoop04 shell]# vim useradd03.sh
    #!/usr/bin/bash
    ##########################################
    # useradd                                #
    # v1.0 by ElegantSmile 8/12/2019         #
    ##########################################
    
    read -p "please input number: " num
    
    while true
    do
            # 判断输入的num是否为数字
            if [[ "${num}"  =~ ^[0-9]+$ ]];then
              break
            else
              echo "error number!"
              read -p "please input number: " num
            fi
    done
    
    read -p "please input prefix: " prefix
    
    while true
    do
            # 判断是否输入prefix
            if [ -n "${prefix}" ];then
              break
            else
              echo "error prefix!"
              read -p "please input prefix: " prefix
            fi
    done
    
    for i in `seq ${num}`
    do
      username=${prefix}${i}
      useradd ${username}
      echo "123" | passwd -stdin ${username} &> /dev/null
      #filename=${prefix}${i}
      #touch ${filename}
      if [ $? -eq 0 ];then
        echo "${username} is created" 
      fi
    
    done
    

    特殊符号复习

    ()

    子shell中执行命令

    [root@hadoop04 ~]# (date)
    Sun Dec  8 21:07:18 CST 2019
    

    (())

    C语言风格的数值比较

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

    $()

    命令替换,相当于反引号``

    [root@hadoop04 shell]# touch `date +%F`.txt
    [root@hadoop04 shell]# ll
    -rw-r--r--. 1 root root   0 Dec  8 21:09 2019-12-08.txt
    # 
    [root@hadoop04 shell]# touch $(date +%F).txt
    [root@hadoop04 shell]# ll
    -rw-r--r--. 1 root root   0 Dec  8 21:09 2019-12-08.txt
    

    $(())

    整数运算

    [root@hadoop04 shell]# echo $((1+2))
    3
    

    {}

    集合

    [root@hadoop04 shell]# touch file{1..10}.txt
    

    ${}

    变量引用

    []

    条件测试:文件测试,数值比较,字符串比较

    [[]]

    除了[]支持的一般条件测试以外,还支持正则表达式 =~

    测试条件之间的逻辑关系在[]和[[]]有所不同

    逻辑与

    [ EXPRESSION1 -a EXPRESSION2 ]
    
    [[ EXPRESSION1 && EXPRESSION2 ]]
    

    逻辑或

    [ EXPRESSION1 -o EXPRESSION2 ]
    
    [[ EXPRESSION1 || EXPRESSION2 ]]
    

    $[]

    整数运算

    执行脚本

    # ./01.sh       需要执行权限       在子 shell 中执行
    # bash 01.sh    不需要执行权限     在子 shell 中执行
    # . 01.sh       不需要执行权限     在当前 shell 中执行
    # source 01.sh  不需要执行权限     在当前 shell 中执行
    

    提示:通常修改系统配置文件中如 /etc/profile 的 PATH 等变量后,使之在当前 shell 中生效

    调试脚本

    # sh -n xxx.sh 仅调试 syntax error
    # sh -vx xxx.sh 以调试的方式执行,查询整个执行过程  
    

    command

    此为补充内容,command可以检查一个对象是否是一个命令

    command -v 对象
    

    示例

    [root@hadoop04 ~]# command -v /etc/hosts; echo $?
    1
    [root@hadoop04 ~]# command -v test; echo $?
    test
    0
    [root@hadoop04 ~]# command -v vim; echo $?
    /usr/bin/vim
    0
    

    测试脚本

    [root@hadoop04 shell_case]# vim command_test.sh
    
    #!/usr/bin/bash
    
    read -p "Please input a command: " com
    
    if command -v "${com}" &> /dev/null;then
            # :即true,此处表示不做任何操作
            :
    else
            echo "you need to yum install ${com}."
    fi
    
    # 测试脚本
    # 输入test命令,脚本无任何显示,表示test是一个命令
    [root@hadoop04 shell_case]# bash command_test.sh
    Please input a command: test
    # 输入/home/test,脚本提示需要安装该命令,表示test不是一个命令或者系统上未装
    [root@hadoop04 shell_case]# bash command_test.sh
    Please input a command: /home/test  
    you need to yum install /home/test.
    
  • 相关阅读:
    EasyUI Combobox组合框(模糊搜索、默认值绑定)
    Asp.Net下载文件时中途失败问题
    VS使用小技巧之——设置调试时启动项目和启动页
    VS使用小技巧之——给代码添加region
    VS使用小技巧之——引入整个文件夹
    VS使用小技巧之——任务列表
    FineUI给表格行内链接设置弹出窗体
    cnpm私服搭建和发布包
    阿里云产品术语和docker
    angularjs1.x的一些知识点整理
  • 原文地址:https://www.cnblogs.com/ElegantSmile/p/12014969.html
Copyright © 2011-2022 走看看