开发者俱乐部

标题: shell 教程之二 测试 [打印本页]

作者: ismeng    时间: 2016-3-13 14:45
标题: shell 教程之二 测试

知道如何将值赋给变量和传递参数之后,您还需要知道如何测试这些值和参数。您已经知道 $?包含来自一个 shell 命令的返回状态。还可以设置该值,将它用于变量声明和赋值,以及我稍后将展示的测试。test命令是一个内建命令,它执行各种测试,并将返回状态设置为 0(成功或 true)或 1(失败或 false)。在本教程后面,我将展示如何使用返回状态来制定决策,比如在 if-then-else结构中。
test和 [test命令,展示了在您的变量 PATH变量没有目录时如何添加它。参见 清单 4。
清单 4. add2path函数
  1. ian@attic-u15:~$ type  add2path
  2. add2path is a function
  3. add2path ()
  4. {
  5.     local augpath augdir;
  6.     augpath=":$PATH:";
  7.     augdir=":$1:";
  8.     test "$augpath" = "${augpath/$augdir}" && PATH="$1:$PATH"
  9. }
复制代码

根据表达式 expr的计算结果,test内建命令将会返回 0(true) 或 1(false)。您还可以使用方括号;test expr和 [ expr ]是等效的。您可以显示 $?来检查返回值。然后可以像以前使用 && 和 || 一样使用返回值。或者您可以使用我将在本教程后面介绍的各种条件结构来测试返回值。 清单 5显示了一些简单的测试例子。
清单 5. 一些简单的测试
  1. ian@attic-u15:~$ test 3 -gt 4 && echo true || echo false
  2. false
  3. ian@attic-u15:~$ [ "abc" != "def" ];echo $?
  4. 0
  5. ian@attic-u15:~$ [ "abc" = "def" ];echo $?
  6. 1
  7. ian@attic-u15:~$ test -d "$HOME" ;echo $?
  8. 0
复制代码

[url=]清单 5[/url]中的第一个示例使用 -gt运算符在两个文字值之间执行算术比较。第二和第三个示例使用了替代语法 [ ]来比较两个字符串相等还是不相等,然后在每种情况下回送 $?的值。最后一个示例使用 -d一元运算符来检查 HOME变量是否是一个目录的名称。
可以使用 -eq(相等)、-ne(不等)、-lt(小于)、-le(小于或等于)、-gt(大于)或 -ge(大于或等于)中的一个运算符来比较算术值。
可以使用 =来比较字符串是否相等,使用 !=比较字符串是否不等,并使用 <和 >确定第一个字符串排在第二个字符串之前还是之后。一元运算符 -z将会测试 null 字符串;如果一个字符串不是 null,-n或 no 运算符返回 true (0)。
<和 >运算符也被 shell 用来进行重定向,所以您必须使用 \<或 \>对它们进行转义。 清单 6显示了字符串测试的更多示例。
清单 6. 更多字符串测试
  1. ian@attic-u15:~$ test "abc" = "def" ;echo $?
  2. 1
  3. ian@attic-u15:~$ [ "abc" != "def" ];echo $?
  4. 0
  5. ian@attic-u15:~$ [ "abc" \< "def" ];echo $?
  6. 0
  7. ian@attic-u15:~$ [ "abc" \> "def" ];echo $?
  8. 1
  9. ian@attic-u15:~$ [ "abc" \< "abc" ];echo $?
  10. 1
  11. ian@attic-u15:~$ [ "abc" \> "abc" ];echo $?
  12. 1
  13. ian@attic-u15:~$ [ -z "abc" ]; echo $?
  14. 1
  15. ian@attic-u15:~$ [ -n "abc" ]; echo $?
  16. 0
复制代码

您可以在文件系统对象上使用许多测试。 表 1显示了一些常见的测试。如果测试的对象存在并具有指定的属性,则结果为 true (0)。
表 1. 常见文件测试
您也可使用 表 2中所示的二元运算符来比较两个文件。
表 2. 文件比较测试
可以使用其他测试来检查文件的权限设置等方面。请参阅 bash 手册页了解更多的细节,或者使用 help test来查看 test内建命令的简略信息。您可以将 help命令用于其他内建命令。
您可以使用一元 -o运算符来测试各种 shell 选项是否已设置。如 清单 7所示,如果 -o 选项已设置,test -o option返回 true (0);否则它返回 false (1)。
清单 7. 测试 shell 选项
  1. ian@attic-u15:~$ # Setting and testing the unset option
  2. ian@attic-u15:~$ set +o nounset
  3. ian@attic-u15:~$ echo $MYTESTVAR

  4. ian@attic-u15:~$ [ -o nounset ];echo $?
  5. 1
  6. ian@attic-u15:~$ # You can also set/unset nounset using set -u or set +u
  7. ian@attic-u15:~$ set -u
  8. ian@attic-u15:~$ echo $MYTESTVAR
  9. bash: MYTESTVAR: unbound variable
  10. ian@attic-u15:~$ test -o nounset; echo $?
  11. 0
复制代码

可以使用 -a二元选项来将表达式与逻辑与 (logical AND) 相组合,使用 -o二元选项来将表达式与逻辑或 (logical OR) 相组合。一元 !运算符对测试的含义求反。可使用圆括号来将表达式分组或覆盖默认优先级。请记住,shell 通常在一个子 shell 内运行括号之间的表达式,所以您必须使用\(和 \)对圆括号进行转义,或者当您不想一个表达式在子 shell 内运行时,可以将这些运算符放在单引号或双引号中。 清单 8演示了 [url=]德·摩根定律[/url]在表达式上的应用。
清单 8. 组合和分组测试
  1. ian@attic-u15:~$ test "a" != "$HOME" -a 3 -ge 4 ; echo $?
  2. 1
  3. ian@attic-u15:~$ [ ! \( "a" = "$HOME" -o 3 -lt 4 \) ]; echo $?
  4. 1
  5. ian@attic-u15:~$ [ ! \( "a" = "$HOME" -o '(' 3 -lt 4 ')' ")" ]; echo $?
  6. 1
  7. ian@attic-u15:~$ # Be careful. ! has higher priority that -a or -o
  8. ian@attic-u15:~$ [ ! \( "a" = "$HOME" \) -o '(' 3 -lt 4 ')'  ]; echo $?
  9. 0
复制代码

test命令很强大,但转义的需求和字符串与算术比较之间的区别可能让它变得不实用。幸运的是,bash 有其他两种方式来设置算术和逻辑表达式的返回代码,如果您熟悉 C、C++ 或 Java 语法,那么它们看起来应该更自然一些。









欢迎光临 开发者俱乐部 (http://xodn.com/) Powered by Discuz! X3.2