1.15 比较与测试

程序中的流程控制是由比较和测试语句来处理的。Bash同样具备多种与UNIX系统级特性相兼容的执行测试的方法。

1.15.1 预备知识

我们可以用ifif else以及逻辑运算符来执行测试,而用一些比较运算符来比较数据项。另外,有一个test命令也可以用来进行测试。让我们来看看如何使用这些命令。

1.15.2 实战演练

if条件:

  1. if condition;
  2. then
  3. commands;
  4. fi

else ifelse

  1. if condition;
  2. then
  3. commands;
  4. elif condition;
  5. then
  6. commands
  7. else
  8. commands
  9. fi

ifelse语句可以进行嵌套。if的条件判断部分可能会变得很长,但可以用逻辑运算符将它变得简洁一些:

  1. [ condition ] && action; # 如果condition为真,则执行action
  2. [ condition ] || action; # 如果condition为假,则执行action

&&是逻辑与运算符,||是逻辑或运算符。写Bash脚本时,这是一个很有用的技巧。现在来了解一下条件和比较操作。

算术比较

条件通常被放置在封闭的中括号内。一定要注意在[]与操作数之间有一个空格。如果忘记了这个空格,脚本就会报错。例如:

  1. [ $var -eq 0 ] or [ $var -eq 0 ]

对变量或值进行算术条件判断:

  1. [ $var -eq 0 ] # 当 $var 等于 0 时,返回真
  2. [ $var -ne 0 ] # 当 $var 为非 0 时,返回真

其他重要的操作符如下所示。

  • -gt:大于。

  • -lt:小于。

  • -ge:大于或等于。

  • -le:小于或等于。

可以按照下面的方法结合多个条件进行测试:

  1. [ $var1 -ne 0 -a $var2 -gt 2 ] # 使用逻辑与-a
  2. [ $var -ne 0 -o var2 -gt 2 ] # 逻辑或 -o

文件系统相关测试

我们可以使用不同的条件标志测试不同的文件系统相关属性。

  • [ -f $file_var ]:如果给定的变量包含正常的文件路径或文件名,则返回真。

  • [ -x $var ]:如果给定的变量包含的文件可执行,则返回真。

  • [ -d $var ]:如果给定的变量包含的是目录,则返回真。

  • [ -e $var ]:如果给定的变量包含的文件存在,则返回真。

  • [ -c $var ]:如果给定的变量包含的是一个字符设备文件的路径,则返回真。

  • [ -b $var ]:如果给定的变量包含的是一个块设备文件的路径,则返回真。

  • [ -w $var ]:如果给定的变量包含的文件可写,则返回真。

  • [ -r $var ]:如果给定的变量包含的文件可读,则返回真。

  • [ -L $var ]:如果给定的变量包含的是一个符号链接,则返回真。

使用方法举例如下:

  1. fpath="/etc/passwd"
  2. if [ -e $fpath ]; then
  3. echo File exists;
  4. else
  5. echo Does not exist;
  6. fi

字符串比较

使用字符串比较时,最好用双中括号,因为有时候采用单个中括号会产生错误,所以最好避开它们。

可以检查两个字符串,看看它们是否相同。

  • [[ $str1 = $str2 ]]:当str1等于str2时,返回真。也就是说,str1str2包含的文本是一模一样的。

  • [[ $str1 == $str2 ]]:这是检查字符串是否相等的另一种写法。

也可以检查两个字符串是否不同。

  • [[ $str1 != $str2 ]]:如果str1str2不相同,则返回真。

我们还可以检查字符串的字母序情况,具体如下所示。

  • [[ $str1 > $str2 ]]:如果str1的字母序比str2大,则返回真。

  • [[ $str1 < $str2 ]]:如果str1的字母序比str2小,则返回真。

  • [[ -z $str1 ]]:如果str1包含的是空字符串,则返回真。

  • [[ -n $str1 ]]:如果str1包含的是非空字符串,则返回真。

1.15 比较与测试 - 图1 注意在= 前后各有一个空格。如果忘记加空格,那就不是比较关系了,而变成了赋值语句。

使用逻辑运算符 &&|| 能够很容易地将多个条件组合起来:

  1. if [[ -n $str1 ]] && [[ -z $str2 ]] ;
  2. then
  3. commands;
  4. fi

例如:

  1. str1="Not empty "
  2. str2=""
  3. if [[ -n $str1 ]] && [[ -z $str2 ]];
  4. then
  5. echo str1 is non-empty and str2 is empty string.
  6. fi

输出如下:

  1. str1 is non-empty and str2 is empty string.

test命令可以用来执行条件检测。用test有助于避免使用过多的括号。之前讲过的[]中的测试条件同样可以用于test命令。

例如:

  1. if [ $var -eq 0 ]; then echo "True"; fi
  2. can be written as
  3. if test $var -eq 0 ; then echo "True"; fi