条件测试

  • 判断某个条件是否满足,需要由测试机制来实现
  • 专用的测试表达式需要由测试命令辅助完成
  • 实现评估不二生命,一边用在条件性环境下进行执行

条件状态

  • 若真,则状态码变量 $? 返回0
  • 若假,则状态码变量 $? 返回1

条件测试命令

  • test 表达式
  • [ 表达式 ] #和test等价,建议使用[ ]
  • [[ 表达式 ]] #相当于增强版的[ ]

注意:表达式前后必须有空白字符

test

[05:19:35 root@C8-3-55 ~]#help test
test: test [表达式]
    对条件表达式进行估值。

    根据 EXPR 表达式的估值以状态 0 (真) 或 1 (伪) 退出。
    表达式可以是一元或者二元的。一元表达式通常用于检测
    文件状态。同时还有字符串操作符和数字比较操作符。

    文件操作符:

      -a 文件        如果文件存在则为真。
      -b 文件        如果文件为块特殊文件则为真。
      -c 文件        如果文件为字符特殊文件则为真。
      -d 文件        如果文件为目录则为真。
      -e 文件        如果文件存在则为真。
      -f 文件        如果文件存在且为常规文件则为真。
      -g 文件        如果文件的组属性设置打开则为真。
      -h 文件        如果文件为符号链接则为真。
      -L 文件        如果文件为符号链接则为真。
      -k 文件        如果文件的粘滞 (sticky) 位设定则为真。
      -p 文件        如果文件为命名管道则为真。
      -r 文件        如果文件对于您是可读的则为真。
      -s 文件        如果文件存在且不为空则为真。
      -S 文件        如果文件是套接字则为真。
      -t 文件描述符   如果文件描述符在一个终端上打开则为真。
      -u 文件        如果文件的用户数行设置打开则为真。
      -w 文件        如果文件对您是可写的则为真
      -x 文件        如果文件对您是可执行的则为真。
      -O 文件        如果文件是被您所有的则为真。
      -G 文件        如果文件被您的组所有则为真。
      -N 文件        如果文件上次被读取之后修改过则为真。

      FILE1 -nt FILE2  如果 file1 文件新于 file2 文件则为真(根据
                       修改日期)。

      FILE1 -ot FILE2  如果 file1 文件旧于 file2 文件则为真。

      FILE1 -ef FILE2  如果 file1 文件是 file2 文件的硬链接则为真。

    字符串操作符

      -z 字符串      如果字符串为空则为真。

      -n 字符串
         字符串      如果字符串不为空则为真。

      STRING1 = STRING2
                     如果 string1 和 string2 字符串相同则为真。
      STRING1 != STRING2
                     如果 string1 和 string2 字符串不相同则为真。
      STRING1 < STRING2
                     如果按字典排序 string1 在 string2 串之前则为真。
      STRING1 > STRING2
                     如果按字典排序 string1 在 string2 串之前则为真。

    其他操作符:

      -o 选项        如果指定 shell 选项启用则为真。
      -v VAR         如果指定 Shell 变量 VAR 已赋值则为真。
      -R VAR         如果指定 Shell 变量 VAR 已赋值且为名称引用则为真。
      ! EXPR         如果表达式 expr 为假则为真。
      EXPR1 -a EXPR2 如果 expr1 和 expr2 都为真则为真。
      EXPR1 -o EXPR2 如果 expr1 和 expr2 有一个为真则为真。

      arg1 OP arg2   算术测试。OP操作符可以是 -eq、-ne、
                     -lt、-le、-gt、或 -ge 中的一个。

    二元算术操作返回真,如果 ARG1 参数等于、不等于、
    小于、小于等于、大于、或者大于等于 ARG2 参数。

    退出状态:
    如果 EXPR 表达式估值为真则返回成功;如果 EXPR 表达式估值
    为假或者使用了无效的参数则返回失败。

中括号 [

[05:20:45 root@C8-3-55 ~]#help [
[: [ 参数... ]
    估值条件表达式。

    是内建命令 "test" 的同义词,但是最后一个参数必须是
    字符 `]',以匹配起始的 `['。

用来对比表达式

[05:22:27 root@C8-3-55 ~]#x=10 ;y=20 ;test $x = $y ;echo $?
1
[05:22:41 root@C8-3-55 ~]#x=20 ;y=20 ;test $x = $y ;echo $?
0
[05:22:49 root@C8-3-55 ~]#x=20 ;y=20 ;[ $x = $y ];echo $?
0

判断变量是否为空

[05:28:32 root@C8-3-55 ~]#A=10;echo $A;[ -z "$A" ];echo $?
10
1
[05:28:45 root@C8-3-55 ~]#A=10;echo $A;unset A;[ -z "$A" ];echo $?
10
0

实例

  • 磁盘空间超80%报警
1 #!/bin/bash
  2 WL=75
  3 USED=`df | grep '^/dev/sd' | grep -Eo '[0-9]+%' | tr -d % | sort -nr | head -1`
  4 [ $USED -ge $WL ] && echo Disk is "$WL"% used! | mail -s "Disk Warning" 123456@789.com
  • 检查IP是否畅通
[05:55:49 root@C8-3-55 ~]#vim cheak_IP.sh
[05:56:25 root@C8-3-55 ~]#cat cheak_IP.sh
#!/bin/bash
IP=$1
ping -c5 -w5 $IP &> /dev/null && echo $IP is UP || echo $IP is DOWN | mail -s "host $IP is down !" 12345@678.com
[05:56:32 root@C8-3-55 ~]#bash cheak_IP.sh 10.0.0.55
10.0.0.55 is UP
  • 生成10.0.0.1/24
echo 10.0.0.{1..254} | tr -s ' ' '\n' > IP.log;cat IP.log

变量测试

  • -v 变量是否被定义
  • -R 变量是否被引用

[[双中括号

支持通配符和正则表达式

[06:20:01 root@C8-3-55 ~]#help [[
[[ ... ]]: [[ 表达式 ]]
    执行条件命令。

    根据条件表达式 EXPRESSION 的估值返回状态0或1。表达式按照
    `test' 内建的相同条件组成,或者可以有下列操作符连接而成:

      ( EXPRESSION )    返回 EXPRESSION 表达式的值
      ! EXPRESSION              如果 EXPRESSION表达式为假则为真,否则为假
      EXPR1 && EXPR2    如果 EXPR1 和 EXPR2 表达式均为真则为真,否则为假
      EXPR1 || EXPR2    如果 EXPR1 和 EXPR2 表达式中有一个为真则为真,否则为假

    当使用 `==' 和 `!=' 操作符时,操作符右边的字符串被用作模式并且执行一个
    匹配。当使用 `=~' 操作符时,操作符右边的字符串被当作正则表达式来进行
    匹配。

    操作符 && 和 || 将不对 EXPR2 表达式进行估值,如果 EXPR1 表达式足够确定
    整个表达式的值。

    退出状态:
    根据 EXPRESSION 的值为0或1。