
循环编程的三种结构.doc
21页第 18 章 shell 编程——循环目标完成此章学 习 后,你将掌握下列内容: 使用 while 结 构,在某条件保持 为 真的情况下重复 执 行一段代 码 使用 until 结 构,重复 执 行一段代 码 ,直到某条件 为 真 使用 for 结 构,遍 历 由空白区分隔的一串参数382 UNIX 系统基础18.1 循环——介绍注释使用循环结构可以重复执行一个命令序列,就和分支结构一样,关键命令的返回码决定继续还是停止执行循环语句test 命令常常用来控制循环语句是否继续执行分支结构的起始点是一个关键词,终点是该关键词的倒序词(if/fi 和 case/esac) ,循环结构与分支结构不同,它起始于一个关键词和一个条件,循环体被包围在 do 和 done 中间第 18 章 shell 编程 ——循环 38318.2 用 let 命令做数学表达式运算注释通常 shell 通过递增一个数值型变量的值来控制循环语句在 shell 脚本中 let 命令可以使用数学表达式,它支持长整型变量该命令的语法如本节幻灯片所示,expression 是一个表达式,可以代表 shell 变量和操作符。
将表达式括在(( ))里面的相当于 let 命令 shell 能辨认的操作符如表 18-1 所示,按优先级从低到高排列表 18-1操 作 符 描 述- 单操作符负号! 逻辑非* / % 乘、除、余数+ - 加、减= 关系型比较== != 等于、不等于= 分配数值384 UNIX 系统基础可以用括号改变一个表达式的计算顺序,如:let “x=x/(y+1)”应该注意的是:很有必要使用双引号使括号的特殊意义失效同样,如果在表达式里有空格,在使用 let 命令或者 (( ))时必须用双引号:let “x=x+(y/2)” 或者 (( x=x+(y/2 ))当使用逻辑操作符和关系操作符(!、=、、==、!=)时,shell 的返回值变量——?,会显示运算结果是 true 还是 false(0 代表 true,1 代表 false) 同样,还是要用双引号防止 shell 将小于等于号和大于等于号理解为输入输出重定向符第 18 章 shell 编程 ——循环 38518.3 while 结构注释while 结构是 shell 提供的一个循环机制,当某条件为真的时候,循环执行 shell 的一段命令(list B) 。
这个条件是否为真由 list A 最后一个命令的返回码决定常常使用 test 或 let命令控制循环,但任何其他可以产生返回码的命令都可以用来控制循环本节幻灯片中的例子可以用 let 命令代替 test 命令来控制循环,如下所示:$ X=1$ while [ $X -le 10 ]>do> echo hello X is $X> let X=X+1> done386 UNIX 系统基础其执行情况如下:(1) 执行 list A 中的命令2) 如果 list A 中最后一个命令的返回码为 0(true ) ,那么执行 list B3) 返回第一步4) 如果 list A 中最后一个命令的返回码不是 0(false) ,跳到紧接 done 之后的第一个命令While 结构流程图如图 18-1 所示图 18-1 While 结构流程图警告 注意使用无限性 while 循 环 有些循 环 的控制命令永 远 返回真 cat while_infinitewhile truedoecho hello第 18 章 shell 编程 ——循环 387done$ while_infinitehellohello...Ctrl + c 388 UNIX 系统基础18.4 while 结构——例子注释本节幻灯片演示了 while 结构的另外两个例子。
例 A 演示的是:提示用户输入一个值,然后根据用户的反应决定是否继续循环例 B 演示的是:循环检验命令行中的每个参数如果参数是一个目录,则显示该目录的内容如果参数不是一个目录,则跳过该参数请注意,使用 shift 这个命令可以一个接一个地访问每一个参数当它与 while 命令结合使用时,会使循环结构变得很灵活无论有 1 个还是 100 个参数,循环会继续进行,直到所有的参数被访问完毕应该注意的是如果想最少执行一次循环,可能需要建立一个 while 循环例 A 将至少执行一次循环体,因为例 A 中的 ans 已经被设置成等同于 yes在例 B 里,如果这个程序不带例 A 中的命令行参数($#=0)执行,那么将不执行这个循环第 18 章 shell 编程 ——循环 38918.5 until 结构注释until 结构是 shell 提供的另一种循环机制,这个结构中的命令系列(list B)会保持循环运行,直到某条件为真与 while 结构相似,这个条件是否为真由 list A 最后一个命令的返回码决定本节幻灯片中例子的执行情况如下:(1)执行 list A 中的命令2)如果 list A 中最后一个命令的返回码不为 0(false) ,那么执行 list B。
3)返回第一步4)如果 list A 中最后一个命令的返回码为 0(true) ,跳到紧接 done 之后的第一个命令390 UNIX 系统基础until 结构流程图如图 18-2 所示图 18-2 until 结构流程图警告 注意使用无限 until 循 环 有些循 环 的控制命令永 远 返回真 X=1$ until> [ $X -eq 0 ]> do> echo hello> donehellohello...Ctrl + c 第 18 章 shell 编程 ——循环 39118.6 until 结构——例子注释本节幻灯片例子的内容与在 while 结构中演示的一样,但这里用 until 结构来实现注意必须将 while 结构中测试条件的逻辑反过来,这样才能符合 until 结构测试条件的逻辑还要注意:until 结构对用户输入的敏感度与 while 结构相比,发生了微小的变化在while 结构中,用户只有输入字符串 yes,这个循环才会继续进行继续循环的条件非常严格而在 until 结构中,用户输入的字符串只要不是 no,这个循环都会继续进行。
until 结构对于继续循环施加的条件,没有 while 结构那么严格当你决定哪种结构最适合你的需要时,你可以将这些问题考虑在内在上面的例子中,是否预定义 ans 变量的值并不太重要,因为这个变量会被初始化为NULL由于 NULL 不等于 no,测试条件会返回 false,于是可以开始执行循环你只需确认在测试表达式中用双引号将$ans 括起来以符合 test 命令语法392 UNIX 系统基础18.7 for 结构注释本节幻灯片中的例子有几个关键字:for、in、do、donevar 代表一个 shell 变量,它的数值在 for 循环的执行过程中决定list 是由空格或 tab 键分隔的一系列字符串,在 for 循环的执行过程中这些字符串将被分配给 var这个结构的执行情况如下:(1) 将 shell 变量 var 的值设为 list 中的第一个字符串2) 执行命令 list A3) 将 shell 变量 var 的值设为 list 中的下一个字符串4) 执行命令 list A5) 继续循环直到 list 中所有项都被赋给变量 varfor 结构流程图如图 18-3 所示第 18 章 shell 编程 ——循环 393图 18-3 for 结构流程图394 UNIX 系统基础18.8 for 结构 ——例子注释for 结构是一个非常灵活的循环结构。
它可以循环访问 shell 创建的任何参数列表通过命令替换,能够很容易地创建一个参数列表由于管道和过滤器提供的功能,几乎可以由任何东西产生一个参数列表如果想多次访问同一个列表,应该将这个列表保存在一个文件中然后用 cat 命令调用这个文件,生成一个参数列表供 for 循环结构使用 cat studentsuser1user2user3user4第 18 章 shell 编程 ——循环 395$ cat for_students_file_copyfor NAME in $(cat students)docp test.file /home/$NAMEchown $NAME /home/$NAME/test.filechmod g-w,o-w /home/$NAME/test.fileecho done $NAMEdone$访问命令行参数可以以命令行参数创建一个列表,如:for i in $*docp $i $HOME/backupsdone或者for i docp $i $HOME/backupsdone396 UNIX 系统基础18.9 break、continue 和 exit 命令注释有些情况下需要在循环的正常终止条件实现之前切断这个循环。
break 和 continuet 命令可以无条件地改变命令执行的流向当某错误发生时,常常用这两个命令终止当前循环当出现无法恢复的局面时,可以用 exit 命令,这时整个程序的执行会结束break 命令会导致循环结束,程序控制转向紧接 done 关键字后面的命令通过 break 命令,能够立即跳出指定的循环,接着执行循环体后面的命令continue 命令与 break 命令稍微有所不同程序执行到 continue 语句时,会跳过循环体里面剩余的命令,然后回到循环体的顶部因此,continue 命令可以结束当前一次循环,但是,还会回到被中断的循环体的顶部,重新开始循环在 while 和 until 循环中,程序会回到初始化列表的开始处继续进行;而 loop 循环会将变量设为列表中的下一个变量值,然后继续执行exit 命令会结束执行某段 shell 程序,而且,如果指定了一个参数值,这个参数值会作为该 shell 程序的返回值如果没有指定参数值,紧接 exit 命令之前的命令的返回值将作为该 shell 程序的返回值return 命令的作用和一个 shell 程序段里的 exit 命令是一样的。
第 18 章 shell 编程 ——循环 397注意 一般情况下, 应该 通 过 循 环 体 顶 部( while、loop)的条件控制,或者通 过 遍 历 列表(for)来 终 止 执 行循 环 体 仅 当循 环 中出 现 非正常条件或者 错误 的条件,才 应 当使用上面提到的几个中断命令例子whilecmd1docmdAcmdBwhilecmdCdocmdEreak 2cmdFdonecmdJcmdKdonecmdX(1) break 2 之后执行的是哪一个命令?(2) 如果将 break 2 替换为 break,break 之后执行的是哪一个命令?(3) 如果将 break 2 替换为 continue 2,continue 2 之后执行的是哪一个命令?(4) 如果将 break 2 替换为 continue,continue 之后执行的是哪一个命令?398 UNIX 系统基础18.10 break 和 continue 命令——例子注释这个例子说明了 break 和 continue 命令的巨大作用本节幻灯片所示的例子中,while循环的检测条件永远为真,说明这是一个无限循环,除非循环。
