开发者俱乐部

标题: shell教程之四: 条件 [打印本页]

作者: ismeng    时间: 2016-3-13 14:59
标题: shell教程之四: 条件

[size=1.166em]您可以使用我目前展示的测试及 &&[size=1.166em]和 ||[size=1.166em]控制运算符来完成大量编程。此外,bash 还包含更熟悉的 if[size=1.166em]-then[size=1.166em]-else[size=1.166em]和 case[size=1.166em]结构。在我展示这些结构和循环结构后,您的工具箱会变得充实得多。
使用 if-then-else语句
[size=1.166em]尽管您目前看到的测试仅返回 0或 1值,但该命令可以返回其他值。本教程后面会介绍更多测试这些值的知识。
[size=1.166em]bash if命令是一个复合命令,它测试一次测试或命令的返回状态 ($?),并基于返回状态为 true (0) 还是 false(非 0)而进行分支。bash 中的 if命令有一个 then子句,其中包含在测试或命令返回 0时要执行的命令列表。该命令还有一个或多个可选的 elif子句。每个可选的elif子句都有一项额外的测试和一个拥有关联的命令列表的 then子句。最后的一个 else子句和关联的命令列表是可选的。如果最初的测试和 elif子句中使用的任何测试的结果都不是 true,则运行最后的 else子句。需要一个终止 fi来标记结构的末尾处。
[size=1.166em]利用您目前在这些教程中学到的知识,现在可以构建一个简单的计算器来计算算术表达式,如 清单 14中所示。
清单 14. 使用 if-then-else计算表达式
  1. ian@attic-u15:~$ function mycalc ()
  2. > {
  3. >   local x
  4. >   if [ $# -lt 1 ]; then
  5. >     echo "This function evaluates arithmetic for you if you give it some"
  6. >   elif (( $* )); then
  7. >   let x="$*"
  8. >     echo "$* = $x"
  9. >   else
  10. >     echo "$* = 0 or is not an arithmetic expression"
  11. >   fi
  12. > }
  13. ian@attic-u15:~$ mycalc 3 + 4
  14. 3 + 4 = 7
  15. ian@attic-u15:~$ mycalc 3 + 4**3
  16. 3 + 4**3 = 67
  17. ian@attic-u15:~$ mycalc 3 + (4**3 /2)
  18. bash: syntax error near unexpected token `('
  19. ian@attic-u15:~$ mycalc 3 + "(4**3 /2)"
  20. 3 + (4**3 /2) = 35
  21. ian@attic-u15:~$ mycalc xyz
  22. xyz = 0 or is not an arithmetic expression
  23. ian@attic-u15:~$ mycalc xyz + 3 + "(4**3 /2)" + abc
  24. xyz + 3 + (4**3 /2) + abc = 35
复制代码

[size=1.166em]计算器使用 local语句将 x声明为只能在 mycalc函数的范围内使用的局部变量。let内建命令有多个可能的选项,与和它密切相关的declare命令一样。请查阅 bash 的手册页或使用 help let来了解更多的信息。
[size=1.166em]您已在 [url=]清单 14[/url]中看到,如果您的表达式使用了 shell 元字符,比如 (、)、*、>和 <,那么这些表达式必须正确转义。但是,您现在有一个方便的小计算器来计算算术表达式,就像 shell 一样。
[size=1.166em]请注意 清单 14中的最后两个示例。将 xyz传递给 mycalc并没有错,但除非您之前已将一个值赋给变量 xyz,否则它将计算为 0。在最后的例子中,该函数不够聪明,无法识别字符值来提醒您,xyz和 abc被静默地当作具有值 0的变量来处理。您可以使用一种字符串模式匹配测试,比如 [[ ! ("$*" == *[a-zA-Z]* ]](或针对您的语言环境的合适形式),以消除任何包含字母字符的表达式,但这会阻止您将 shell 变量用作输入。它还会阻止您在输入中使用十六进制表示法,因为十六进制表示法(比如 0x0f表示十进制树 15)可能包含字母。事实上,您可以在 shell 中(通过 base#表示法)使用最多 64 个 base 字符,所以您的输入可以合法地包含任何字母字符,以及 _和 @。对于八进制和十六进制的特殊情况,可以使用更常见的表示法,也就是说,在八进制数前面添加 0,在十六进制数前面添加 0x 或 0X。清单 15显示了一些示例。
清单 15. 使用不同的 base 字符来计算
  1. ian@attic-u15:~$ mycalc 015
  2. 015 = 13
  3. ian@attic-u15:~$ mycalc 0xff
  4. 0xff = 255
  5. ian@attic-u15:~$ mycalc 29#37
  6. 29#37 = 94
  7. ian@attic-u15:~$ mycalc 64#1az
  8. 64#1az = 4771
  9. ian@attic-u15:~$ mycalc 64#1azA
  10. 64#1azA = 305380
  11. ian@attic-u15:~$ mycalc 64#1azA_@
  12. 64#1azA_@ = 1250840574
  13. ian@attic-u15:~$ mycalc 64#1az*64**3 + 64#A_@
  14. 64#1az*64**3 + 64#A_@ = 1250840574
复制代码

[size=1.166em]对输入的其他处理不属于本教程的讨论范围,所以请审慎地使用您计算器。
[size=1.166em]elif语句很方便,可以帮助您简化脚本中的缩进。 清单 16展示了如何对 mycalc函数使用 type命令来显示 [url=]清单 14[/url]的 elif语句的等效形式。
清单 16. 类型 mycalc
  1. ian@attic-u15:~$ type mycalc
  2. mycalc is a function
  3. mycalc ()
  4. {
  5.     local x;
  6.     if [ $# -lt 1 ]; then
  7.         echo "This function evaluates arithmetic for you if you give it some";
  8.     else
  9.         if (( $* )); then
  10.             let x="$*";
  11.             echo "$* = $x";
  12.         else
  13.             echo "$* = 0 or is not an arithmetic expression";
  14.         fi;
  15.     fi
  16. }


复制代码








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