⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000019.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;&nbsp;流程控制&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;tcl支持分支和循环。分支语句可以使用if和switch实现。if语句的和C语言类似,如&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;{&nbsp;$&nbsp;x&nbsp;&lt;&nbsp;0&nbsp;}&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;set&nbsp;y&nbsp;10;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;注意判断子句也需要使用花括号。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;与C语言一样,tcl的if语句也可以使用else和elseif。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;switch语句的用法有点类似这样:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;switch&nbsp;&nbsp;$x&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;0&nbsp;{&nbsp;set&nbsp;y&nbsp;10;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;10&nbsp;{&nbsp;set&nbsp;y&nbsp;100;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;20&nbsp;{&nbsp;set&nbsp;y&nbsp;400;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;与C的switch语句不同,每次只有符合分支值的子句才被执行。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;循环命令主要由for,foreach和while构成,而且每一个都可以使用break和continue&nbsp;<BR>子句。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;for语句的格式有点类似这样:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;for&nbsp;{&nbsp;set&nbsp;i&nbsp;0}&nbsp;{$i&nbsp;&lt;&nbsp;10}&nbsp;{&nbsp;incr&nbsp;i}&nbsp;{puts&nbsp;$i}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;将会输出从1到9的整数。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;如果用while循环,这个句子可以写成&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;while&nbsp;{$i&nbsp;&lt;&nbsp;10&nbsp;}&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;puts&nbsp;$i;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;incr&nbsp;i;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;foreach是对于集合中的每一个元素执行一次命令,大致的命令格式是&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;foreach&nbsp;[变量]&nbsp;{&nbsp;集合&nbsp;}&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;语句;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;例如&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;%&nbsp;foreach&nbsp;j&nbsp;{&nbsp;1&nbsp;3&nbsp;5}&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;put&nbsp;$j;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>1&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>3&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>5&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;函数&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;如同在一般的编程语言里面一样,在tcl里面也可以定义函数,这是通过proc命令实现&nbsp;<BR>的:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;proc&nbsp;my_proc&nbsp;{i}{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;puts&nbsp;$i;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;这样就定义了一个名字叫proc的函数,它只是在终端显示输入变元的内容。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;要使用这个函数,简单地输入它的名字:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;%&nbsp;my_proc&nbsp;{&nbsp;5&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;5&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;如果变元的数目是0,只要使用空的变元列表,例如&nbsp;proc&nbsp;my_proc&nbsp;{}&nbsp;{语句;}&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;尽管tcl还可以处理更复杂的过程,但是我们不再介绍了,例如文件的读写以及tk图形&nbsp;<BR>语言,因为我们处理tcl的主要目标就是理解expect,对于更复杂的编程工作,我们建议&nbsp;<BR>你使用perl。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;11.1.2&nbsp;expect&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect是建立在tcl基础上的一个工具,它用来让一些需要交互的任务自动化地完成。&nbsp;<BR>我们首先从一个简单的例子开始,如同在这一节一开始就提到的,我们想设置一个自动&nbsp;<BR>的文件下载程序。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;我们看一看这样的一个例子脚本:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#!&nbsp;/usr/bin/expect&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;spawn&nbsp;ftp&nbsp;202.199.248.11&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;Name&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;ftp\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;Password:&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;nothing\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;apply&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;cd&nbsp;/pub/UNIX/Linux/remoteX\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;successful.&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;bin\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;set&nbsp;to&nbsp;I&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;get&nbsp;exceed5.zip\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;complete.&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;quit\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;这个是什么意思?呵呵,就是个自动下载程序。第一行说明这个程序应该调用/usr/b&nbsp;<BR>in/expect去执行,然后的就是expect命令。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;察看expect的手册页面(man&nbsp;expect)可以得到一个很长的expect说明,可惜其中关于&nbsp;<BR>expect的语法仍然介绍的不够。一般来说,expect主要用在需要自动执行人机交互的过&nbsp;<BR>程中,例如fsck程序,这个程序会不断地提问&quot;yes/no&quot;,像这样的命令就可以用expect&nbsp;<BR>来完成。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;spawn语句在expect脚本中用于启动一个新的进程,在我们的程序中,spawn&nbsp;ftp&nbsp;202&nbsp;<BR>.199.248.11就是去执行ftp程序,接下来,就是expect和send的指令对了。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;每一对expect和send指令代表一个信息/回应。如果这样说不好理解的话,那么可以看&nbsp;<BR>一看ftp的具体执行过程:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;ftp&nbsp;202.199.248.11&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;Connected&nbsp;to&nbsp;202.199.248.11.&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;220&nbsp;mail.asnc.edu.cn&nbsp;FTP&nbsp;server&nbsp;(BeroFTPD&nbsp;1.3.3(3)&nbsp;Sun&nbsp;Feb&nbsp;20&nbsp;15:52:49&nbsp;CST&nbsp;<BR>&nbsp;2000.&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;Name&nbsp;(202.199.248.11:wanghy):&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;显然,一旦连接成功,服务器会返回一个Name(202.199.248.11:wanghy):的字符串来&nbsp;<BR>要求客户给出用户名。expect语句简单地在返回信息中查询你给出的字符串,一旦成功&nbsp;<BR>就执行下面的命令,现在,expect&nbsp;&quot;&nbsp;Name&quot;已经成功地找到了Name字符串,接下来可以&nbsp;<BR>执行send命令了。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send命令比expect命令更简单,它简单地向标准输入提交你设定的字符串,现在设置&nbsp;<BR>为send&nbsp;&nbsp;&quot;ftp\r&quot;表示等到登录信息之后就给出一个输入ftp回车,也就是标准的登录过&nbsp;<BR>程。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;下面的行与这些行完全一样,只是机械地等待服务器的回应,并且提交自己的输入。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;要使用这个expect脚本,你只需要将它设置为可执行的属性,然后执行它,expect就&nbsp;<BR>会执行你需要的服务。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;由于expect是tcl的扩展,所以你在expect文件中可以象tcl脚本一样设置变量和程序&nbsp;<BR>流程。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;现在我们看一看我们还能够如何改进我们的expect脚本。ftp命令可能会失败,比如远&nbsp;<BR>端的机器可能会无法提供服务,或者在启动ftp命令时本地机器发生问题。为了处理这一&nbsp;<BR>类的问题,我们可以使用expect的timeout选项来设置超时的话expect脚本自动退出:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#!&nbsp;/usr/bin/expect&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;spawn&nbsp;ftp&nbsp;202.199.248.11&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;timeout&nbsp;exit&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;Connect&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;………………&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;注意这里面使用的花括号。它的含义是使用一组并列表达式。使用并列表达式的主要&nbsp;<BR>原因是这样:如果使用下面的指令对:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;timeout&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;exit&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;那么由于expect脚本是顺序执行的,那么当程序执行到这个expect的时候就会阻塞,&nbsp;<BR>所以程序会一直等待到timeout然后退出。并列表达式则是相当于switch的行为,只要列&nbsp;<BR>出的几项内容有一项得到满足,expect命令就得到满足,于是程序可以正常执行。上面&nbsp;<BR>的脚本表示,如果连接ftp的时候发生了超时,那么就退出,否则,一旦发现Connect应&nbsp;<BR>答,说明服务器已经正常了,那么就可以继续运行了。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;我们可以看看用tcl能够对我们的expect脚本提供什么帮助。我们可以设置让expect脚&nbsp;<BR>本不断地连接远端服务器的服务,直到正常建立连接开始,为此,我们可以把建立连接&nbsp;<BR>的命令放在一个循环里面,并且根据回应的不同自动选择重新输入命令还是继续执行:&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;spawn&nbsp;ftp&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;while&nbsp;{1}&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;&quot;ftp&gt;&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;send&nbsp;&quot;o&nbsp;202.199.248.11\r&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;expect&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&quot;Connected&quot;&nbsp;break&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;refused&quot;&nbsp;{&nbsp;sleep&nbsp;10}&nbsp;&nbsp;;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>}&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;这里使用了我们在tcl语言中讲到的while和break命令,熟悉C的读者应该很容易看出&nbsp;<BR>它的行为:不断地等待ftp&gt;提示符,在提示符下面发送连接远端服务器的命令,如果服&nbsp;<BR>务器回应是refused(连接失败),就等待10秒钟,然后开始下一次循环;如果是Conne&nbsp;<BR>cted,那么就跳出循环执行下面的命令。sleep是expect的一个标准命令,表示暂停若干&nbsp;<BR>秒钟。&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -