zoukankan      html  css  js  c++  java
  • shell 的条件表达式及逻辑操作符简单介绍

    查看系统的shell:

    cat /etc/shells

    文件测试表达式:

      -f 文件  文件存在且为普通文件则真,即测试表达式成立。

      -d 文件  文件存在且为目录文件则真,即测试表达式成立。

      -s 文件  文件存在且文件大小不为0则真,即测试表达式成立。

      -e 文件  文件存在则真,即测试表达式成立。只要有文件就行,要区别 -f 。

      -r 文件  文件存在且可读则真,即测试表达式成立。

      -w 文件 文件存在且可写则真,即测试表达式成立。

      -x 文件  文件存在且可执行则真,即测试表达式成立。

      -L 文件   文件存在且为链接文件则真,即测试表达式成立。

      a –nt b    文件a比文件b新则真,即测试表达式成立,根据文件修改时间来计算

      a –nt b    文件a比文件b旧则真,即测试表达式成立,根据文件修改时间来计算

    特别说明:这些操作符号对于[[]]、[]、test几乎是通用的,更多的操作符请man test查询。

    普通文件测试表达式:

    [root@lamp01 ~]# mkdir bqh1
    [root@lamp01 ~]# ll -d ./bqh1
    drwxr-xr-x. 2 root root 4096 1月  27 21:51 ./bqh1
    [root@lamp01 ~]# [ -d bqh1 ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -f bqh1.log ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# touch ./bqh1.log
    [root@lamp01 ~]# [ -f bqh1.log ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -e bqh1.log ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -e bqh2.log ]&&echo 1||echo 0
    [root@lamp01 ~]# [ -r bqh1 ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -w bqh1 ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -x bqh1 ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# chmod 000 bqh1
    [root@lamp01 ~]# ll
    d---------. 2 root root  4096 1月  27 21:51 bqh1
    [root@lamp01 ~]# [ -x bqh1 ]&&echo 1||echo 0
    1

    提示:文件的读写执行等属性,不光是根据文件属性,而是当前执行脚本的用户根据测试选项是否真的可操作。

    测试shell变量举例:

    [root@lamp01 ~]# a=/etc/services
    [root@lamp01 ~]# b=/etc/
    [root@lamp01 ~]# [ -f $a ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -d $a ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# [ -d $b ]&&echo 1||echo 0
    1

    特殊例子:如果变量不加双引号,测试结果可能不正确。

    [root@lamp01 ~]# echo $c
    [root@lamp01 ~]# [ -f "$c" ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# [ -f $c ]&&echo 1||echo 0
    1    #$c明明不存在的,却返回1

    使用条件表达式时,多个返回值时,可以使用大括号的用法,格式如下:

    当条件不成立就会执行大括号内的所有命令内容:

    [root@lamp01 ~]# [ 1 -ne 1 ]||{ echo "my name is bqh" ; echo "my name is jyw" ;}
    my name is bqh
    my name is jyw
    [root@lamp01 ~]# 

    字符串测试表达式:

      字符串测试操作符:

      -z “字符串”               若串长度为0则真

      -n ”字符串“               若串长度不为0则真

      “字符串1”=“字符串2”     若串1等于串2则真,可以使用‘==’代替‘=’

      “字符串1”!=“字符串2”    若串1不等于串2则真,但不能用‘!==’代替‘!=’

     测试如下:

    [root@lamp01 ~]# [ -n "abc" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -n "" ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# [ -z "" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -z "abc" ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# [ ! -z "abc" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# a="bqh"
    [root@lamp01 ~]# [ -n "$a" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -z $a ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# [ ! -z $a ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ "$a" != "bqh1" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ "$a" = "bqh1" ]&&echo 1||echo 0
    0

    等号两端空格带来的问题:

    [root@lamp01 ~]# [ "abc"="1" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ "abc" = "1" ]&&echo 1||echo 0
    0

    不加引号带来的问题:

    [root@lamp01 ~]# a=""
    [root@lamp01 ~]# [ $a = abc  ]&&echo 1||echo 0
    -bash: [: =: unary operator expected
    0
    [root@lamp01 ~]# [ $a = "abc"  ]&&echo 1||echo 0
    -bash: [: =: unary operator expected
    0
    [root@lamp01 ~]# [ "$a" = "abc"  ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# 

    特别注意:

    1.比较符合两端有空格。

    2.字符串测试操作符号务必要用“”引起来。

    整数表达式:

      -eq:      ==或=                测试两个整数是否相等;比如 $A -eq $B

      -ne:       !=                 测试两个整数是否不等;不等,为真;相等,为假;

      -gt:        >                测试一个数是否大于另一个数;大于,为真;否则,为假;

      -lt:        <                测试一个数是否小于另一个数;小于,为真;否则,为假;

      -ge:        >=                 大于或等于

      -le:       <=                 小于或等于

     在使用中中注意:

    1、[]及test中使用字母模式。

    2、在 (()) 和 [[]] 中使用符合模式。

    提示:

     “<”符号意思是小于,if[[ "$a" < "$b" ]],if [ "$a" < "$b" ] 在单[]中需要转义,因为shell也用<和>重定向。

     “>”符号意思是大于,if[[ "$a" > "$b" ]],if [ "$a" > "$b" ] 在单[]中需要转义,因为shell也用<和>重定向。

      “=”符号意思是等于,if[[ "$a" = "$b" ]],if [ "$a" = "$b" ] 在单[]中不需要转义。

    测试:

    [root@lamp01 ~]# [ 2>1 ] && echo 1 || echo 0
    0  ==>这里的结果逻辑不对,条件应该成立,应该返回1
    [root@lamp01 ~]# [ 2>1 ] && echo 1 || echo 0
    1 ==>转义后是正确的
    [root@lamp01 ~]# [ 2 -eq 1 ] && echo 1 || echo 0
    0
    [root@lamp01 ~]# [ 2 -gt 1 ] && echo 1 || echo 0
    1
    [root@lamp01 ~]# [ 2 -lt 1 ] && echo 1 || echo 0
    0
    [root@lamp01 ~]# [ 2 -ge 1 ] && echo 1 || echo 0
    1
    [root@lamp01 ~]# [ 2 -le 1 ] && echo 1 || echo 0
    0
    [root@lamp01 ~]# [ 2 = 1 ] && echo 1 || echo 0
    0
    [root@lamp01 ~]# [ 2 = 2 ] && echo 1 || echo 0
    1
    [root@lamp01 ~]# [ 2 != 2 ] && echo 1 || echo 0
    0
    

    “=” 和 “!=” 在[]中使用不需要转义,包含“>”和“<”的符号在[]中使用需要转义,对于数字不转义的结果未必会报错,但是结果可能会不对。

    [root@lamp01 ~]# [[ 2 > 1 ]] && echo 1 || echo 0
    1
    [root@lamp01 ~]# [[ 2 > 11 ]] && echo 1 || echo 0 ====>只比较第一位,逻辑结果不对。
    1
    [root@lamp01 ~]# [[ 2 > 31 ]] && echo 1 || echo 0 ====>只比较第一位,逻辑结果不对。
    0

    数比较不要加双引号:系统脚本例子

     

    整数比较推荐方法:

    [ $numl -eq $num2 ]  ===>注意空格,和比较符号

    (($num1>$num2))  ===>无需空格,常规数据比较符号。

    --------------------------------------------------------------------------------------------------------

    测试结果结论:

    1、整数加双引号也是对的。

    2、[]用>号的写法语法没错,逻辑结果不对。

    3、[[]]用-eq等的写法也是对的,[[]]用>写法也可能不对,只比较第一位,逻辑结果不对。

    逻辑操作符

    在[]和test中使用         在[[]]中使用             说明

         -a                               &&               and与,两端都为真,则真

         -o                                 ||                or或,两端有一个真,则真

           !                                  !                  not非,相反则为真

    测试:

    [root@lamp01 ~]# a1=/etc/rc.local
    [root@lamp01 ~]# a2=/etc/services
    [root@lamp01 ~]# [ -f "$a1" && -f "$a2" ]&&echo 1||echo 0
    -bash: [: missing `]'
    0
    [root@lamp01 ~]# [ -f "$a1" -a -f "$a2" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [[ -f "$a1" && -f "$a2" ]]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -n "$a1" -a -z "$a2" ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# [ -n "$a1" -o  "$a1"="$a2" ]&&echo 1||echo 0
    1

    如果你非要单中括号加&&或||可以用以下方法:

    [root@lamp01 ~]# a1=/etc/rc.local
    [root@lamp01 ~]# a2=/etc/services
    [root@lamp01 ~]# [ -f "$a1" ]||[ -e "$a2" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ -f "$a1" ]&&[ -e "$a2" ]&&echo 1||echo 0
    1
    

     !非逻辑符号:

    [root@lamp01 ~]# [ -f "$a1" ]&&[ -e "$a2" ]&&echo 1||echo 0
    1
    [root@lamp01 ~]# [ ! -f "$a1" ]&&[ -e "$a2" ]&&echo 1||echo 0
    0
    [root@lamp01 ~]# test -f "$a1" -a -e "$a2" &&echo 1||echo 0
    1
    [root@lamp01 ~]# test !  -f "$a1" -a -e "$a2" &&echo 1||echo 0
    0
    

    提醒:

    1、“-a” 和 “-o” 和“!”逻辑操作符号用于 [] 中使用。

    2、“&&”和“||” 和“!”逻辑操作符号用户 [[]] 中使用。

    3、注意括号两端,必须要有空格。

    4、test用法和 [] 相同。

    5、多个[]之间以及多个[[]]之间,或者任意混合中间逻辑操作符都是&&或||。

  • 相关阅读:
    mysql的基础增删改查(一)
    用sql的avg(score)求完平均值后,保存两位小数的方法(用于查询或视图)
    异常java.lang.IllegalArgumentException:attempt to create delete event with null entity
    jsp传到java的control层的方法
    Java基础知识整理(一)
    DataTables warning (table id = 'DataTables_Table_0');错误解决办法!
    关于HTML学习整理(一)
    jQuery EasyUI 数据网格
    EasyUI DataGrid分页数据绑定
    SQL输出矩阵
  • 原文地址:https://www.cnblogs.com/su-root/p/10328427.html
Copyright © 2011-2022 走看看