14.1.5 逻辑测试符和逻辑运算符

逻辑测试用于连接多个测试条件,并返回整个表达式的值。逻辑测试主要有逻辑非、逻辑与、逻辑或3种。逻辑测试符如表14-4所示。

表14-4 逻辑测试符

14.1.5 逻辑测试符和逻辑运算符 - 图1

举例如下:


  1. #
  2. 例一:逻辑非的使用
  3. #
  4. 测试值为真的表达式在使用逻辑非后,表达式变为假,反之亦然
  5. [root@localhost ]# [ ! -e varlog/messages ]
  6. [root@localhost ]# echo $?
  7. 1
  8. #
  9. 例二:逻辑与的使用
  10. #
  11. 表达式都为真,整个表达式才返回真,否则返回假
  12. [root@localhost ]# [ -e varlog/messages -a -e varlog/messages01 ]
  13. [root@localhost ]# echo $?
  14. 1
  15. #
  16. 例三:逻辑或的使用
  17. #
  18. 测试表达式中只要有真,则整个表达式返回真
  19. [root@localhost ]# [ -e varlog/messages -o -e varlog/messages01 ]
  20. [root@localhost ]# echo $?
  21. 0

如果读者曾经学过其他的编程语言,一定知道“逻辑运算符”也有逻辑非、逻辑与、逻辑或3种判断符号。事实上,在Shell中也有逻辑运算符,除了写法和使用方式不一样外,其作用和含义都是相同的,如表14-5所示。

表14-5 逻辑运算符

14.1.5 逻辑测试符和逻辑运算符 - 图2

下面是一个使用逻辑运算符改写逻辑测试符的例子。通过此例,读者可以很容易地了解这两种方式在使用上的差异。


  1. [root@localhost ]# ! [ -e varlog/messages ]
  2. [root@localhost ]# echo $?
  3. 1
  4. [root@localhost ]# [ -e varlog/messages ] && [ -e varlog/messages01 ]
  5. [root@localhost ]# echo $?
  6. 1
  7. [root@localhost ]# [ -e varlog/messages ] || [ -e varlog/messages01 ]
  8. [root@localhost ]# echo $?
  9. 0

不管是逻辑运算符还是逻辑测试符,在做逻辑与、逻辑或运算时都有共同的特点。比如逻辑与,由于需要所有的表达式都为0整体才返回0,因此在计算expression1结果为0后才会进行expression2的计算,如果expression2返回0则会进行expression3的计算,如果在计算过程中任何一部分的计算值非0,则不会再计算后面的表达式。如果一开始就计算出expression1为非0,则可以断言整个表达式一定是返回非0,就没有必要计算expression2和expression3了。


  1. #
  2. 逻辑与运算
  3. expression1 && expression2 && expression3
  4. #
  5. 逻辑与测试
  6. [ expression1 -a expression2 -a expression3 ]

而对逻辑或来说,只要有一个表达式返回0,则可以断言整个表达式的返回值是0,所以如果计算expression1的值为0,就不用再进行expression2和expression3的计算了。


  1. #
  2. 逻辑或运算
  3. expression1 || expression2 || expression3
  4. #
  5. 逻辑或测试
  6. [ expression1 -o expression2 -o expression3 ]

在实践过程中,常会将逻辑与、逻辑或的这些特点联合起来使用,使用的方式如下:


  1. expression && DoWhenExpressionTrue || DoWhenExpressionFalse

在这段代码中,从左到右分别用&&、||连接,这时,Shell首先计算expression,并返回其值。如果返回真,则会继续执行&&后的代码DoWhenExpressionTrue,如果该语句执行成功,则expression&&DoWhenExpressionTrue整体返回0,使用||连接的DoWhenExpressionFalse代码将不会被执行;如果expression返回假,则跳过DoWhenExpressionTrue,这时由于expression&&DoWhenExpressionTrue整体返回假,则用||连接的代码段DoWhenExpressionFalse一定会被执行。由此可以看到,在保证DoWhenExpressionTrue一定能返回真的情况下,上述代码段其实就是一个隐形的if-then-else语法(这将会在下一小节介绍)。