﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-淡泊明志、宁静致远-随笔分类-通信技术</title><link>http://www.cnitblog.com/houcy/category/7230.html</link><description>A Diamond is just a piece of Coal that did well under Pressure.</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 06:26:49 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 06:26:49 GMT</pubDate><ttl>60</ttl><item><title>wavecom modem使用说明</title><link>http://www.cnitblog.com/houcy/archive/2010/04/22/65531.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Thu, 22 Apr 2010 05:38:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2010/04/22/65531.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/65531.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2010/04/22/65531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/65531.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/65531.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="96%" border=0>
    <tbody>
        <tr>
            <td align=middle>WAVECOM MODEM或开发板使用说明</td>
        </tr>
        <tr>
            <td>
            <p><strong><span>硬件连接：</span></strong></p>
            <p><span>1．<span>&nbsp;&nbsp; </span></span><span>将<span>15P—9P数据线连接开发板及计算机。</span></span></p>
            <p><span>2．<span>&nbsp;&nbsp; </span></span><span>SIM卡插入开发板SIM卡座中。</span></p>
            <p><span>3．<span>&nbsp;&nbsp; </span></span><span>将<span>4P电源插入电源插头。</span></span></p>
            <p><span>4．<span>&nbsp;&nbsp; </span></span><span>检查合格后加电即可。</span></p>
            <p><span>简单的测试步骤</span></p>
            <p><strong><span>软件连接：</span></strong></p>
            <p><span>1．<span>&nbsp;&nbsp; </span></span><span>打开计算机的超级终端</span></p>
            <p><span>2．<span>&nbsp;&nbsp; </span></span><span>连接到<span>COM1或COM2</span></span></p>
            <p><span>3．<span>&nbsp;&nbsp; </span></span><span>环境设置：波特率<span>9600，数据位8，停止位1，奇偶校验无，硬件控制数据流。</span></span></p>
            <p><strong><span>在超级终端下：</span></strong></p>
            <p><span>输入：</span></p>
            <p><span>AT《CR》</span></p>
            <p><span>返回<span>OK</span></span></p>
            <p><span>TEXT模式下（AT+CMGF=1）</span></p>
            <p><strong><span>收发短信：</span></strong></p>
            <p><span>发：<span>AT+CMGS=电话号码《CR》</span></span></p>
            <p><span>返回：<span>&gt; 输入短信内容《CTRL+Z》</span></span></p>
            <p><span>收：<span>AT+CMGR=接收号《CR》</span></span></p>
            <p><span>即可返回短信内容</span></p>
            <p><strong><span>删除短信：</span></strong></p>
            <p><span>AT+CMGD=1，1（或1，4）</span></p>
            <p><span>即可</span></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cnitblog.com/houcy/aggbug/65531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2010-04-22 13:38 <a href="http://www.cnitblog.com/houcy/archive/2010/04/22/65531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IC卡读卡原理 【转】</title><link>http://www.cnitblog.com/houcy/archive/2010/04/22/65529.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Thu, 22 Apr 2010 05:27:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2010/04/22/65529.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/65529.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2010/04/22/65529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/65529.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/65529.html</trackback:ping><description><![CDATA[<p class=unnamed1 align=left>
<table cellSpacing=0 cellPadding=0 width="96%" border=0>
    <tbody>
        <tr>
            <td style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-WEIGHT: bolder; FONT-SIZE: 16px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px" align=middle>非接触式射频感应IC卡读卡原理</td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 8px; BORDER-TOP: #cccccc 1px dotted; PADDING-LEFT: 8px; PADDING-BOTTOM: 8px; PADDING-TOP: 8px; BORDER-BOTTOM: #cccccc 1px dotted"><span style="FONT-SIZE: 9pt; COLOR: #33cccc; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font style="COLOR: #000000">
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-char-indent-size: 9.0pt; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">非接触式射频感应</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">IC</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卡读卡原理卡片的电气部分只由一个天线和</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">ASIC(IC)</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">组成。天线：</span><span style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman"> </font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卡片的天线是只有几组绕线的线圈，很适于封装到</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">IS0</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卡片中。</span><span style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman"> <span lang=EN-US>ASIC</span></font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman"> </font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卡片的</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">ASIC</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由一个高速（</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">106KB</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">波特率）的</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">RF</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口，一个控制单元和一个定容量的</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">EEPROM</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">组成。</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><o:p></o:p></span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-char-indent-size: 9.0pt; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工作原理：</span><span style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman"> </font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">读写器电路向</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">IC</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卡发一组固定频率的电磁波，卡片内有一个</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">LC</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">串联谐振电路，其频率与读写器发射的频率相同，在电磁波的激励下，</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">LC</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">谐振电路产生共振，从而使电容内有了电荷，在这个电容的另一端，接有一个单向导通的电子泵，将电容内的电荷送到另一个电容内储存，当所积累的电荷达到</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; mso-bidi-font-size: 12.0pt"><font face="Times New Roman">2V</font></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，此电容可做为电源为其它电路提供工作电压，将卡内数据发射出去或接取读写器的数据。</span><span lang=EN-US style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"></font></span></p>
            </td>
        </tr>
    </tbody>
</table>
<strong><br><br>常见的读卡器款式</strong>：</p>
<p class=unnamed1 align=left>普通读卡器：<br><img height=120 src="http://www.wiegand.com.cn/pic/canpin/reader/wg1026/WG1026-kh_w120h120.jpg" width=120><img height=150 src="http://www.wiegand.com.cn/pic/canpin/reader/qita/hid6005_150.jpg" width=150><img height=120 src="http://www.wiegand.com.cn/pic/canpin/reader/wg1026/WG1026-OL_w120h120.jpg" width=120><img height=120 src="http://www.wiegand.com.cn/pic/canpin/reader/qita/mot605_120.jpg" width=120></p>
<p class=unnamed1 align=left><br>密码键盘读卡器：<br><img height=120 src="http://www.wiegand.com.cn/pic/canpin/reader/wg1029/wg1029H120.jpg" width=120><img height=150 src="http://www.wiegand.com.cn/pic/canpin/reader/qita/hid5355K_150.jpg" width=150><img height=120 src="http://www.wiegand.com.cn/pic/canpin/reader/wg1029/WG1029_w120h120.jpg" width=120><img height=120 src="http://www.wiegand.com.cn/pic/canpin/reader/qita/motARK501.jpg" width=120></p>
<p class=unnamed1 align=left>长距离读卡器<br><img height=150 src="http://www.wiegand.com.cn/pic/canpin/reader/qita/wgv468_150.jpg" width=150></p>
<img src ="http://www.cnitblog.com/houcy/aggbug/65529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2010-04-22 13:27 <a href="http://www.cnitblog.com/houcy/archive/2010/04/22/65529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>awk的内建函数</title><link>http://www.cnitblog.com/houcy/archive/2008/08/31/48572.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Sun, 31 Aug 2008 02:49:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2008/08/31/48572.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/48572.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2008/08/31/48572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/48572.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/48572.html</trackback:ping><description><![CDATA[<strong><font size=4>awk<font face=SimHei>的内建函数</font><br></font><font size=3>1. <font face=SimHei>字符串函数</font></font></strong><br><font size=2>sub函数匹配记录中最大、最靠左边的子字符串的正则表达式，并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。格式如下：<br></font>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub (regular expression, substitution string):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub (regular expression, substitution string, target string)</font><font size=2></font></td>
        </tr>
    </tbody>
</table>
实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ sub(/test/, "mytest"); print }' testfile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ sub(/test/, "mytest"); $1}; print }' testfile</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>第一个例子在整个记录中匹配，替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub<br></font><font size=2>第二个例子在整个记录的第一个域中进行匹配，替换只发生在第一次匹配发生的时候。<br></font><font size=2>gsub函数作用如sub，但它在整个文档中进行匹配。格式如下：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gsub (regular expression, substitution string)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gsub (regular expression, substitution string, target string)</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ gsub(/test/, "mytest"); print }' testfile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ gsub(/test/, "mytest"), $1 }; print }' testfile</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>第一个例子在整个文档中匹配test，匹配的都被替换成mytest。<br></font><font size=2>第二个例子在整个文档的第一个域中匹配，所有匹配的都被替换成mytest。<br></font><font size=2>index函数返回子字符串第一次被匹配的位置，偏移量从位置1开始。格式如下：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index(string, substring)</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>$ awk '{ print index("test", "mytest") }' testfile</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例返回test在mytest的位置，结果应该是3。<br></font><font size=2>length函数返回记录的字符数。格式如下：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; length( string )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; length</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ print length( "test" ) }' <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ print length }' testfile</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>第一个实例返回test字符串的长度。<br></font><font size=2>第二个实例返回testfile文件中第条记录的字符数。<br></font><font size=2>substr函数返回从位置1开始的子字符串，如果指定长度超过实际长度，就返回整个字符串。格式如下：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; substr( string, starting position )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; substr( string, starting position, length of string )</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ print substr( "hello world", 7,11 ) }' </font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>上例截取了world子字符串。<br></font><font size=2>match函数返回在字符串中正则表达式位置的索引，如果找不到指定的正则表达式则返回0。match函数会设置内建变量RSTART为字符串中子字符串的开始位置，RLENGTH为到子字符串末尾的字符个数。substr可利于这些变量来截取字符串。函数格式如下：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; match( string, regular expression )</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>$ awk '{start=match("this is a test",/[a-z]+$/); print start}'<br>$ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>第一个实例打印以连续小写字符结尾的开始位置，这里是11。<br></font><font size=2>第二个实例还打印RSTART和RLENGTH变量，这里是11(start)，11(RSTART)，4(RLENGTH)。<br></font><font size=2>toupper和tolower函数可用于字符串大小间的转换，该功能只在gawk中有效。格式如下：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; toupper( string )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tolower( string )</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>实例:<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>$ awk '{ print toupper("test"), tolower("TEST") }'</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>split函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供，则按当前FS值进行分割。格式如下：<br></font><font size=2>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; split( string, array, field separator )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; split( string, array )</font></td>
        </tr>
    </tbody>
</table>
实例：<br>
<table>
    <tbody>
        <tr>
            <td><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ split( "20:18:00", time, ":" ); print time[2] }'</font></td>
        </tr>
    </tbody>
</table>
</font><font size=2>上例把时间按冒号分割到time数组内，并显示第二个数组元素18。<br></font><br><font size=4><strong>2. <font face=SimHei>时间函数</font><br></strong></font><font size=2>systime函数返回从1970年1月1日开始到当前时间(不计闰年)的整秒数。格式如下：<br></font>
<table>
    <tbody>
        <tr>
            <td>systime()</td>
        </tr>
    </tbody>
</table>
实例：<br>
<table>
    <tbody>
        <tr>
            <td>$ awk '{ now = systime(); print now }'</td>
        </tr>
    </tbody>
</table>
<font size=2>strftime函数使用C库中的strftime函数格式化时间。格式如下:<br>
<table>
    <tbody>
        <tr>
            <td>systime( [format specification][,timestamp] )</td>
        </tr>
    </tbody>
</table>
</font>
<p><strong>Table 3. 日期和时间格式说明符<br>
<table style="BORDER-COLLAPSE: collapse" borderColor=#000000 cellSpacing=0 cellPadding=0 width="100%" border=1>
    <tbody>
        <tr>
            <td align=middle width="10%"><strong>格式</strong></td>
            <td align=middle><strong>描述</strong> </td>
        </tr>
        <tr>
            <td>%a</td>
            <td>星期几的缩写(Sun)</td>
        </tr>
        <tr>
            <td>%A</td>
            <td>星期几的完整写法(Sunday)</td>
        </tr>
        <tr>
            <td>%b</td>
            <td>月名的缩写(Oct)</td>
        </tr>
        <tr>
            <td>%B</td>
            <td>月名的完整写法(October)</td>
        </tr>
        <tr>
            <td>%c</td>
            <td>本地日期和时间</td>
        </tr>
        <tr>
            <td>%d</td>
            <td>十进制日期</td>
        </tr>
        <tr>
            <td>%D</td>
            <td>日期 08/20/99</td>
        </tr>
        <tr>
            <td>%e</td>
            <td>日期，如果只有一位会补上一个空格</td>
        </tr>
        <tr>
            <td>%H</td>
            <td>用十进制表示24小时格式的小时</td>
        </tr>
        <tr>
            <td>%I</td>
            <td>用十进制表示12小时格式的小时</td>
        </tr>
        <tr>
            <td>%j</td>
            <td>从1月1日起一年中的第几天</td>
        </tr>
        <tr>
            <td>%m</td>
            <td>十进制表示的月份</td>
        </tr>
        <tr>
            <td>%M</td>
            <td>十进制表示的分钟</td>
        </tr>
        <tr>
            <td>%p</td>
            <td>12小时表示法(AM/PM)</td>
        </tr>
        <tr>
            <td>%S</td>
            <td>十进制表示的秒</td>
        </tr>
        <tr>
            <td>%U</td>
            <td>十进制表示的一年中的第几个星期(星期天作为一个星期的开始)</td>
        </tr>
        <tr>
            <td>%w</td>
            <td>十进制表示的星期几(星期天是0)</td>
        </tr>
        <tr>
            <td>%W</td>
            <td>十进制表示的一年中的第几个星期(星期一作为一个星期的开始)</td>
        </tr>
        <tr>
            <td>%x</td>
            <td>重新设置本地日期(08/20/99)</td>
        </tr>
        <tr>
            <td>%X</td>
            <td>重新设置本地时间(12：00：00)</td>
        </tr>
        <tr>
            <td>%y</td>
            <td>两位数字表示的年(99)</td>
        </tr>
        <tr>
            <td>%Y</td>
            <td>当前月份</td>
        </tr>
        <tr>
            <td>%Z</td>
            <td>时区(PDT)</td>
        </tr>
        <tr>
            <td>%%</td>
            <td>百分号(%)</td>
        </tr>
    </tbody>
</table>
</strong>实例：<br>
<table>
    <tbody>
        <tr>
            <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ now=strftime( "%D", systime() ); print now }'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ awk '{ now=strftime("%m/%d/%y"); print now }'</td>
        </tr>
    </tbody>
</table>
<strong><font size=3>3.<font face=SimHei> 内建数学函数</font></font></strong><br>
<table style="BORDER-COLLAPSE: collapse" borderColor=#000000 cellSpacing=0 cellPadding=0 width="100%" border=1>
    <tbody>
        <tr>
            <td align=middle width="20%"><strong>函数名称</strong></td>
            <td align=middle><strong>返回值</strong> </td>
        </tr>
        <tr>
            <td>atan2(x,y)</td>
            <td>y,x范围内的余切</td>
        </tr>
        <tr>
            <td>cos(x)</td>
            <td>余弦函数</td>
        </tr>
        <tr>
            <td>exp(x)</td>
            <td>求幂</td>
        </tr>
        <tr>
            <td>int(x)</td>
            <td>取整</td>
        </tr>
        <tr>
            <td>log(x)</td>
            <td>自然对数</td>
        </tr>
        <tr>
            <td>rand()</td>
            <td>随机数</td>
        </tr>
        <tr>
            <td>sin(x)</td>
            <td>正弦</td>
        </tr>
        <tr>
            <td>sqrt(x)</td>
            <td>平方根</td>
        </tr>
        <tr>
            <td>srand(x)</td>
            <td>x是rand()函数的种子</td>
        </tr>
        <tr>
            <td>int(x)</td>
            <td>取整，过程没有舍入</td>
        </tr>
        <tr>
            <td>rand()</td>
            <td>产生一个大于等于0而小于1的随机数</td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://www.cnitblog.com/houcy/aggbug/48572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2008-08-31 10:49 <a href="http://www.cnitblog.com/houcy/archive/2008/08/31/48572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>awk环境变量和运算符</title><link>http://www.cnitblog.com/houcy/archive/2008/08/31/48571.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Sun, 31 Aug 2008 02:16:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2008/08/31/48571.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/48571.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2008/08/31/48571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/48571.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/48571.html</trackback:ping><description><![CDATA[<strong><font size=4>awk<font face=SimHei>的环境变量</font></font></strong><font size=2><br></font>
<p>
<table style="BORDER-COLLAPSE: collapse" borderColor=#000000 cellSpacing=0 cellPadding=0 width="100%" border=1>
    <tbody>
        <tr>
            <td align=middle width="15%"><strong>变量</strong></td>
            <td align=middle><strong>描述</strong></td>
        </tr>
        <tr>
            <td>$n</td>
            <td>当前记录的第n个字段，字段间由FS分隔。</td>
        </tr>
        <tr>
            <td>$0</td>
            <td>完整的输入记录。</td>
        </tr>
        <tr>
            <td>ARGC</td>
            <td>命令行参数的数目。</td>
        </tr>
        <tr>
            <td>ARGIND</td>
            <td>命令行中当前文件的位置(从0开始算)。</td>
        </tr>
        <tr>
            <td>ARGV</td>
            <td>包含命令行参数的数组。</td>
        </tr>
        <tr>
            <td>CONVFMT</td>
            <td>数字转换格式(默认值为%.6g)</td>
        </tr>
        <tr>
            <td>ENVIRON</td>
            <td>环境变量关联数组。</td>
        </tr>
        <tr>
            <td>ERRNO</td>
            <td>最后一个系统错误的描述。</td>
        </tr>
        <tr>
            <td>FIELDWIDTHS</td>
            <td>字段宽度列表(用空格键分隔)。</td>
        </tr>
        <tr>
            <td>FILENAME</td>
            <td>当前文件名。</td>
        </tr>
        <tr>
            <td>FNR</td>
            <td>同NR，但相对于当前文件。</td>
        </tr>
        <tr>
            <td>FS</td>
            <td>字段分隔符(默认是任何空格)。</td>
        </tr>
        <tr>
            <td>IGNORECASE</td>
            <td>如果为真，则进行忽略大小写的匹配。</td>
        </tr>
        <tr>
            <td>NF</td>
            <td>当前记录中的字段数。</td>
        </tr>
        <tr>
            <td>NR</td>
            <td>当前记录数。</td>
        </tr>
        <tr>
            <td>OFMT</td>
            <td>数字的输出格式(默认值是%.6g)。</td>
        </tr>
        <tr>
            <td>OFS</td>
            <td>输出字段分隔符(默认值是一个空格)。</td>
        </tr>
        <tr>
            <td>ORS</td>
            <td>输出记录分隔符(默认值是一个换行符)。</td>
        </tr>
        <tr>
            <td>RLENGTH</td>
            <td>由match函数所匹配的字符串的长度。</td>
        </tr>
        <tr>
            <td>RS</td>
            <td>记录分隔符(默认是一个换行符)。</td>
        </tr>
        <tr>
            <td>RSTART</td>
            <td>由match函数所匹配的字符串的第一个位置。</td>
        </tr>
        <tr>
            <td>SUBSEP</td>
            <td>数组下标分隔符(默认值是\034)。</td>
        </tr>
    </tbody>
</table>
<br><br><strong><font size=5><font face=黑体>awk运算符</font></font></strong></p>
<p>
<table style="BORDER-COLLAPSE: collapse" borderColor=#000000 cellSpacing=0 cellPadding=0 width="100%" border=1>
    <tbody>
        <tr>
            <td align=middle width="30%"><strong>运算符</strong></td>
            <td align=middle><strong>描述</strong> </td>
        </tr>
        <tr>
            <td>= += -= *= /= %= ^= **=</td>
            <td>赋值</td>
        </tr>
        <tr>
            <td>?:</td>
            <td>C条件表达式</td>
        </tr>
        <tr>
            <td>||</td>
            <td>逻辑或</td>
        </tr>
        <tr>
            <td>&amp;&amp;</td>
            <td>逻辑与</td>
        </tr>
        <tr>
            <td>~ ~!</td>
            <td>匹配正则表达式和不匹配正则表达式</td>
        </tr>
        <tr>
            <td>&lt; &lt;= &gt; &gt;= != ==</td>
            <td>关系运算符</td>
        </tr>
        <tr>
            <td>空格</td>
            <td>连接</td>
        </tr>
        <tr>
            <td>+ -</td>
            <td>加，减</td>
        </tr>
        <tr>
            <td>* / &amp;</td>
            <td>乘，除与求余</td>
        </tr>
        <tr>
            <td>+ - !</td>
            <td>一元加，减和逻辑非</td>
        </tr>
        <tr>
            <td>^ ***</td>
            <td>求幂</td>
        </tr>
        <tr>
            <td>++ --</td>
            <td>增加或减少，作为前缀或后缀</td>
        </tr>
        <tr>
            <td>$</td>
            <td>字段引用</td>
        </tr>
        <tr>
            <td>in</td>
            <td>数组成员</td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://www.cnitblog.com/houcy/aggbug/48571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2008-08-31 10:16 <a href="http://www.cnitblog.com/houcy/archive/2008/08/31/48571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Chapter 3 “Getting Started With Expect”</title><link>http://www.cnitblog.com/houcy/archive/2008/08/24/48324.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Sun, 24 Aug 2008 14:10:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2008/08/24/48324.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/48324.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2008/08/24/48324.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/48324.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/48324.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="90%" border=0>
    <tbody>
        <tr>
            <td colSpan=2><img height=37 alt="Search the Catalog" isMap src="http://oreilly.com/graphics_new/catalog_header_buttons.gif" width=515 align=bottom useMap=#catalog_header_buttons border=0> <map name=catalog_header_buttons>
            <area shape=RECT coords=407,17,512,32 href="/catalog/search.html">
            <area shape=RECT coords=431,3,512,18 href="/catalog/prdindex.html"></map></td>
        </tr>
        <tr>
            <td vAlign=top width="25%"><a href="http://oreilly.com/catalog/expect/"><img alt="Exploring Expect" hspace=10 src="http://oreilly.com/catalog/covers/expect.s.gif" align=left vspace=10 border=0 valign="top"><u><font color=#0000ff> </font></u></a></td>
            <td vAlign=top height=105><br>
            <h2>Exploring Expect</h2>
            <h3>A Tcl-based Toolkit for Automating Interactive Programs</h3>
            <font size=-1>By Don Libes<br>1st Edition December 1994<br>1-56592-090-2, Order Number: 0902<br>602 pages, $32.95 </font></td>
        </tr>
    </tbody>
</table>
<hr noShade SIZE=1>
<!--sample chapter begins -->
<blockquote>
<h2 class=ChapterTitle>Chapter 3<br>Getting Started With Expect</h2>
<div>
<div>
<p class=BodyStart>Three commands are central to the power of Expect: <em class=Code>send</em> , <em class=Code>expect</em> , and <em class=Code>spawn</em> .<em class=SpreadSpace> </em>The <em class=Code>send</em> command sends strings to a process, the <em class=Code>expect</em> command waits for strings from a process, and the <em class=Code>spawn</em> command starts a process.</p>
<p class=Body>In this chapter, I will describe these commands and another one that is very useful: <em class=Code>interact</em> .<em class=SpreadSpace> </em>To best understand this chapter, it will help to have some basic familiarity with Tcl.<em class=SpreadSpace> </em>If you are wondering about a command that is not explained, look it up in the index for a reference in the previous chapter and read about it there.</p>
<div>
<h3 class=HeadA><a name=89311></a>The send Command</h3>
<p class=Body>The <em class=Code>send</em> command takes a string as an argument and sends it to a process.<em class=SpreadSpace> </em>For example:</p>
<p class=Code>send "hello world"</p>
<p class=Body>This sends the string "<em class=Code> hello world</em> " (without the quotes).<em class=SpreadSpace> </em>If Expect is already interacting with a program, the string will be sent to that program.<em class=SpreadSpace> </em>But initially, <em class=Code>send</em> will send to the standard output.<em class=SpreadSpace> </em>Here is what happens when I type this to the Expect interpreter interactively:</p>
<p class=Code>expect1.1&gt; <em class=Input>send "hello world"</em> </p>
<p class=Code>hello worldexpect1.2&gt;</p>
<p class=Body>The <em class=Code>send</em> command does not format the string in any way, so after it is printed the next Expect prompt gets appended to it without any space.<em class=SpreadSpace> </em>To make the prompt appear on a different line, put a newline character at the end of the string.<em class=SpreadSpace> </em>A newline is represented by "<em class=Code> \n</em> ".</p>
<div>
<h5 class=CodeA>expect1.1&gt; <em class=Input>send "hello world\n"</em> </h5>
<p class=Code>hello world</p>
</div>
<div>
<h5 class=CodeZ>expect1.2&gt; </h5>
<p class=Body>If these commands are stored in a file, <em class=Code>speak</em> , the script can be executed from the UNIX command line:</p>
<p class=Code>% <em class=Input>expect speak</em> </p>
<p class=Code>hello world</p>
<p class=Code>%</p>
<p class=Body><a name=55097></a>With a little magic it is possible to invoke the file as just "<em class=Code> speak</em> " rather than "<em class=Code> expect speak</em> ".<em class=SpreadSpace> </em>On most systems it suffices to insert the line "<em class=Code> #!/usr/local/bin/expect --</em> " and say "<em class=Code> chmod +x speak; rehash</em> ".<em class=SpreadSpace> </em>I will explain this in more detail in <a class=XRef href="http://oreilly.com/catalog/expect/chapter/cmdlineargs.html#90435"></a>.<em class=SpreadSpace> </em>For now, just take it on faith.</p>
</div>
</div>
<div>
<h3 class=HeadA><a name=54215></a>The expect Command</h3>
<p class=Body><em class=Code>expect</em> is the opposite of <em class=Code>send</em> .<em class=SpreadSpace> </em>The <em class=Code>expect</em> command waits for a response, usually from a process.<em class=SpreadSpace> </em><em class=Code>expect</em> can wait for a specific string, but more often <em class=Code>expect</em> is used to wait for any string that matches a given pattern.<em class=SpreadSpace> </em>Analogous to <em class=Code>send</em> , the <em class=Code>expect</em> command initially waits for characters from the keyboard<a class=footnote href="http://oreilly.com/catalog/expect/chapter/ch03.html#pgfId-9292"><u><font color=#606420>1</font></u></a>.<em class=SpreadSpace> </em>Using them, I can create a little conversation:</p>
<p class=Code>expect "hi\n"</p>
<p class=Code>send "hello there!\n"</p>
<p class=Body>When run, the interaction looks like this:</p>
<p class=Code><em class=Input>hi</em> </p>
<p class=Code>hello there!</p>
<p class=Body><a name=28852></a>I typed the string <em class=Code>hi</em> and then pressed return.<em class=SpreadSpace> </em>My input matched the pattern "<em class=Code> hi\n</em> ".<em class=SpreadSpace> </em>Ideally, a return would be matched with "<em class=Code> \r</em> "; however, the UNIX terminal driver translates a return to "<em class=Code> \n</em> ".<a class=footnote href="http://oreilly.com/catalog/expect/chapter/ch03.html#pgfId-9276"><u><font color=#606420>2</font></u></a> As you will see later on, it is rarely necessary to have to worry about this mapping because most of Expect's interactions occur with programs not users, and programs do not "press return".<em class=SpreadSpace> </em>Nonetheless, it is occasionally useful to expect input from people.<em class=SpreadSpace> </em>Plus, it is much easier to experiment with Expect this way.</p>
<p class=Body>If <em class=Code>expect</em> reads characters that do not match the expected string, it continues waiting for more characters.<em class=SpreadSpace> </em>If I had typed <em class=Code>hello</em> followed by a return, <em class=Code>expect</em> would continue to wait for "<em class=Code> hi\n</em> ".</p>
<p class=Body>When the matching string is finally typed, <em class=Code>expect</em> returns.<em class=SpreadSpace> </em>But before returning, <em class=Code>expect</em> stores the matched characters in a variable called <em class=Code>expect_out(0,string)</em> .<em class=SpreadSpace> </em>All of the matched characters plus the characters that came earlier but did not match are stored in a variable called <em class=Code>expect_out(buffer)</em> . <em class=Code>expect</em> does this every time it matches characters.<em class=SpreadSpace> </em>The names of these variables may seem odd, but they will make more sense later on.</p>
<p class=Body>Imagine the following script:</p>
<p class=Code>expect "hi\n"</p>
<p class=Code>send "you typed &lt;$expect_out(buffer)&gt;"</p>
<p class=Code>send "but I only expected &lt;$expect_out(0,string)&gt;"</p>
<p class=Body>The angle brackets do not do anything special.<em class=SpreadSpace> </em>They will just appear in the output, making it clear where the literal text stops and the variable values start.<em class=SpreadSpace> </em>When run the script looks like this:</p>
<p class=Code><em class=Input>Nice weather, eh?</em> </p>
<p class=Code><em class=Input>hi</em> </p>
<p class=Code>you typed &lt;Nice weather, eh?</p>
<p class=Code>hi&gt;</p>
<p class=Code>but I only expected &lt;hi&gt;</p>
<p class=Body>I typed "<em class=Code> Nice weather, eh</em> " &lt;return&gt; "<em class=Code> hi</em> " &lt;return&gt;. <em class=Code>expect</em> reported that it found the <em class=Code>hi</em> but it also found something unexpected: "<em class=Code> Nice weather, eh?\n</em> ".</p>
</div>
<div>
<h3 class=HeadA><a name=37960></a>Anchoring</h3>
<p class=Body>Finding unexpected data in the input does not bother <em class=Code>expect</em> .<em class=SpreadSpace> </em>It keeps looking until it finds something that matches.<em class=SpreadSpace> </em>It is possible to prevent <em class=Code>expect</em> from matching when unexpected data arrives before a pattern.<em class=SpreadSpace> </em>The caret (<em class=Code> ^</em> ) is a special character that only matches the beginning of the input.<em class=SpreadSpace> </em>If the first character of the pattern is a caret, the remainder of the pattern must match starting at the beginning of the incoming data.<em class=SpreadSpace> </em>It cannot skip over characters to find a valid match.<em class=SpreadSpace> </em>For example, the pattern <em class=Code>^hi</em> matches <em class=Code>hiccup</em> but not <em class=Code>sushi</em> .</p>
<p class=Body>The dollar sign (<em class=Code> $</em> ) is another special character.<em class=SpreadSpace> </em>It matches the end of the data.<em class=SpreadSpace> </em>The pattern <em class=Code>hi$</em> matches <em class=Code>sushi</em> but not <em class=Code>hiccup</em> .<em class=SpreadSpace> </em>And the pattern <em class=Code>^hi$</em> matches neither <em class=Code>sushi</em> nor <em class=Code>hiccup</em> .<em class=SpreadSpace> </em>It matches <em class=Code>hi</em> and nothing else.</p>
<p class=Body>Patterns that use the <em class=Code>^</em> or <em class=Code>$</em> are said to be <em class=Emphasis>anchored</em> .<em class=SpreadSpace> </em>Some programs, such as <em class=Code>sed</em> , define anchoring in terms of the beginning of a line.<em class=SpreadSpace> </em>This makes sense for <em class=Code>sed</em> , but not for <em class=Code>expect</em> . <em class=Code>expect</em> anchors at the beginning of whatever input it has received without regard to line boundaries.</p>
<p class=Body>When patterns are <em class=Emphasis>not</em> anchored, patterns match beginning at the earliest possible position in the string.<em class=SpreadSpace> </em>For example, if the pattern is <em class=Code>hi</em> and the input is <em class=Code>philosophic</em> , the <em class=Code>hi</em> in <em class=Code>philo</em> is matched rather than the <em class=Code>hi</em> in <em class=Code>sophic</em> .<em class=SpreadSpace> </em>In the next section, this subtlety will become more important.</p>
</div>
<div>
<h3 class=HeadA><a name=95078></a>What Happens When Input Does Not Match</h3>
<p class=Body>Once <em class=Code>expect</em> has matched data to a pattern, it moves the data to the <em class=Code>expect_out</em> variable as I showed earlier.<em class=SpreadSpace> </em>The matched data is no longer eligible to be matched.<em class=SpreadSpace> </em>Additional matches can only take place with new data.</p>
<p class=Body>Consider the following fragment:</p>
<p class=Code>expect "hi"</p>
<p class=Code>send "$expect_out(0,string) $expect_out(buffer)"</p>
<p class=Body>If I execute these two commands, Expect waits for me to enter <em class=Code>hi</em> .<em class=SpreadSpace> </em>If I enter <em class=Code>philosophic</em> followed by a return, Expect finds the <em class=Code>hi</em> and prints:</p>
<p class=Code>hi phi</p>
<p class=Body>If I execute the two commands again, Expect prints:</p>
<p class=Code>hi losophi</p>
<p class=Body>Even though there were two occurrences of <em class=Code>hi</em> , the first time <em class=Code>expect</em> matched the first one, moving it into <em class=Code>expect_out</em> .<em class=SpreadSpace> </em>The next <em class=Code>expect</em> started from where the previous one had left off.</p>
<p class=Body>With simple patterns like these, <em class=Code>expect</em> always stops waiting and returns immediately after matching the pattern.<em class=SpreadSpace> </em>If <em class=Code>expect</em> receives more input than it needs, that input is remembered for the possibility of matching in later <em class=Code>expect</em> commands.<em class=SpreadSpace> </em>In other words, <em class=Code>expect</em> <em class=Emphasis>buffers</em> its input.<em class=SpreadSpace> </em>This allows <em class=Code>expect</em> to receive input before it is actually ready to use it.<em class=SpreadSpace> </em>The input will be held in an <em class=Definition>input buffer</em> until an <em class=Code>expect</em> pattern matches it.<em class=SpreadSpace> </em>This buffer is internal to <em class=Code>expect</em> and is not accessible to the script in any way except by matching patterns against it.</p>
<p class=Body>After the second <em class=Code>expect</em> above, the buffer must hold <em class=Code>c\n</em> .<em class=SpreadSpace> </em>This is all that was left after the second <em class=Code>hi</em> in <em class=Code>philosophic</em> .<em class=SpreadSpace> </em>The <em class=Code>\n</em> is there, of course, because after entering the word, I pressed return.</p>
<p class=Body>What happens if the commands are run again?<em class=SpreadSpace> </em>In this case, <em class=Code>expect</em> is not going to find anything to match <em class=Code>hi</em> .<em class=SpreadSpace> </em>The <em class=Code>expect</em> command eventually <em class=Emphasis>times</em> <em class=Emphasis>out</em> and returns.<em class=SpreadSpace> </em>By default, after 10 seconds <em class=Code>expect</em> gives up waiting for input that matches the pattern.<em class=SpreadSpace> </em>This ability to give up waiting is very useful.<em class=SpreadSpace> </em>Typically, there is some reasonable amount of time to wait for input after which there is no further point to waiting.<em class=SpreadSpace> </em>The choice of 10 seconds is good for many tasks.<em class=SpreadSpace> </em>But there is no hard rule.<em class=SpreadSpace> </em>Programs almost never guarantee that "if there is no response after 17 seconds, then the program or computer has crashed".</p>
<p class=Body><a name=81486></a>The timeout is changed by setting the variable <em class=Code>timeout</em> using the Tcl <em class=Code>set</em> command.<em class=SpreadSpace> </em>For example, the following command sets the timeout to 60 seconds.</p>
<p class=Code>set timeout 60</p>
<p class=Body>The value of <em class=Code>timeout</em> must be an integral number of seconds.<em class=SpreadSpace> </em>Normally timeouts are nonnegative, but the special case of -1 signifies that <em class=Code>expect</em> should wait forever.<em class=SpreadSpace> </em>A timeout of 0 indicates that <em class=Code>expect</em> should not wait at all.</p>
<p class=Body>If <em class=Code>expect</em> times out, the values of <em class=Code>expect_out</em> are not changed.<em class=SpreadSpace> </em>Therefore, the commands above would have printed:</p>
<p class=Code>hi losophi</p>
<p class=Body>even though only <em class=Code>c\n</em> remained in the buffer.</p>
</div>
<div>
<h3 class=HeadA><a name=54879></a>Pattern-Action Pairs</h3>
<p class=Body>You can directly associate a command with a pattern.<em class=SpreadSpace> </em>Such commands are referred to as <em class=Emphasis>actions</em> .<em class=SpreadSpace> </em>The association is made by listing the action immediately after the pattern in the <em class=Code>expect</em> command itself.<em class=SpreadSpace> </em>For example:</p>
<p class=Code>expect "hi" {send "You said $expect_out(buffer)"}</p>
<p class=Body>The command "<em class=Code> send "You said $expect_out(buffer)"</em> " will be executed if and only if <em class=Code>hi</em> is matched from the input.</p>
<p class=Body>Additional pattern-action pairs can be listed after the first one:</p>
<p class=Code>expect "hi" { send "You said hi\n" } \</p>
<p class=Code>"hello" { send "Hello yourself\n" } \</p>
<p class=Code>"bye" { send "That was unexpected\n" }</p>
<p class=Body>This command looks for "<em class=Code> hi</em> ", "<em class=Code> hello</em> ", and "<em class=Code> bye</em> " simultaneously.<em class=SpreadSpace> </em>If any of the three patterns are found, the action listed immediately after the first matching pattern is executed.<em class=SpreadSpace> </em>It is possible that none of them match within the time period defined by the timeout.<em class=SpreadSpace> </em>In this case, <em class=Code>expect</em> stops waiting and execution continues with the next command in the script.<em class=SpreadSpace> </em>Actions can be associated with timeouts, and I will describe that in <a class=XRef href="http://oreilly.com/catalog/expect/chapter/globpat.html#12007"></a>.</p>
<p class=Body>In the <em class=Code>expect</em> command, it does not matter how the patterns and actions visually line up.<em class=SpreadSpace> </em>They can all appear on a single line if you can fit them, but lining up the patterns and actions usually makes it easier for a human to read them.</p>
<p class=Body>Notice how all the actions are embedded in braces.<em class=SpreadSpace> </em>That is because <em class=Code>expect</em> would otherwise misinterpret the command.<em class=SpreadSpace> </em>What is the problem with the following command?</p>
<p class=Code>expect "hi" send "You said hi\n" ;# wrong!</p>
<p class=Body>In this case, <em class=Code>hi</em> is taken as a pattern, <em class=Code>send</em> is the associated action and "<em class=Code> You said hi\n</em> " is taken as the next pattern.<em class=SpreadSpace> </em>This is obviously not what was intended!<em class=SpreadSpace> </em>If the action is more than a single argument, you must enclose it in braces.</p>
<p class=Body><a name=34178></a>Because Tcl commands normally terminate at the end of a line, a backslash is used to continue the command.<em class=SpreadSpace> </em>Since all but the last line must end with a backslash, it can be a bit painful to cut and paste lines.<em class=SpreadSpace> </em>You always have to make sure that the backslashes are there.<em class=SpreadSpace> </em>The <em class=Code>expect</em> command supports an alternate syntax that lets you put all the arguments in one big braced list.<em class=SpreadSpace> </em>For example:</p>
<p class=Code>expect {</p>
<p class=Code>"hi" { send "You said hi\n"}</p>
<p class=Code>"hello" { send "Hello yourself\n"}</p>
<p class=Code>"bye" { send "That was unexpected\n"}</p>
<p class=Code>}</p>
<p class=Body>The initial open brace causes Tcl to continue scanning additional lines to complete the command.<em class=SpreadSpace> </em>Once the matching brace is found, all of the patterns and actions between the outer braces are passed to <em class=Code>expect</em> as arguments.</p>
<p class=Body>Here is another way of writing the same <em class=Code>expect</em> commands:</p>
<p class=Code>expect "hi" {</p>
<p class=Code>send "You said hi\n"</p>
<p class=Code>} "hello" {</p>
<p class=Code>send "Hello yourself\n"</p>
<p class=Code>} "bye" {</p>
<p class=Code>send "That was unexpected\n"</p>
<p class=Code>}</p>
<p class=Body>Each open brace forces more lines to be read until a close brace is encountered.<em class=SpreadSpace> </em>But on the same line that the close brace appears, another open brace causes the search to continue once again for a mate.<em class=SpreadSpace> </em>Even though all the arguments are not enclosed by yet another pair of braces, the whole command is nonetheless read as one.<em class=SpreadSpace> </em>This style has the advantage that it is easier to have multi-line actions, and the actions can be moved around more easily because they are not on the same line as their actions (presuming your editor can cut and paste by lines more easily than half-lines).<em class=SpreadSpace> </em>If you want to further separate the patterns, you can rewrite it as:</p>
<p class=Code>expect {</p>
<p class=Code>"hi" {</p>
<p class=Code>send "You said hi\n"</p>
<p class=Code>}</p>
<p class=Code>"hello" {</p>
<p class=Code>send "Hello yourself\n"</p>
<p class=Code>}</p>
<p class=Code>"bye" {</p>
<p class=Code>send "That was unexpected\n"</p>
<p class=Code>}</p>
<p class=Code>}</p>
<p class=Body>While this looks like it wastes a lot of space, you can now cut and paste the first action (<em class=Code> hi</em> ) without disturbing the "<em class=Code> expect {</em> ".<em class=SpreadSpace> </em>You can decide for yourself which style is appropriate.<em class=SpreadSpace> </em>Depending on the context, I may use any one of these.<em class=SpreadSpace> </em>If commands are very short, I may even pack them all on a line.<em class=SpreadSpace> </em>For example, the following command has two patterns, "<em class=Code> exit</em> " and "<em class=Code> quit</em> ".<em class=SpreadSpace> </em>Their actions are listed immediately to the right of each pattern.</p>
<p class=Code>expect "exit" {exit 1} "quit" abort</p>
</div>
<div>
<h3 class=HeadA>Example -- <a name=65809></a>Timed Reads In The Shell</h3>
<p class=Body>I have shown how to wait for input for a given amount of time and how to send data back.<em class=SpreadSpace> </em>I will wrap this up in a script called <em class=Code>timed-read</em> .</p>
<p class=Code>#!/usr/local/bin/expect --</p>
<p class=Code>set timeout $argv</p>
<p class=Code>expect "\n" {</p>
<p class=Code>send [string trimright "$expect_out(buffer)" "\n"]</p>
<p class=Code>}</p>
<p class=Body>The timeout is read from the variable <em class=Code>argv</em> which is predefined to contain the arguments from the command line.<em class=SpreadSpace> </em>I will describe <em class=Code>argv</em> further in <a class=XRef href="http://oreilly.com/catalog/expect/chapter/cmdlineargs.html#45084"></a>.<em class=SpreadSpace> </em>The next command waits for a line to be entered.<em class=SpreadSpace> </em>When it is, "<em class=Code> string trimright ... "\n"</em> " returns the string without the newline on the end of it, and that is returned as the result of the script.</p>
<p class=Body>You can now call this script from a shell as follows:</p>
<p class=Code>% <em class=Input>timed-read 60</em> </p>
<p class=Body>This command waits 60 seconds for the user to type a line and then it returns whatever the user typed.<em class=SpreadSpace> </em>This ability is very useful.<em class=SpreadSpace> </em>For example, suppose your system reboots automatically upon a crash.<em class=SpreadSpace> </em>You could set up your system so that it gives someone the opportunity to log in to straighten out any problems before coming up all the way.<em class=SpreadSpace> </em>Of course, if the machine crashes when no one is around, you do not want the computer to wait until someone comes in just to tell it to go ahead.<em class=SpreadSpace> </em>To do so, just embed this in your shell script:</p>
<div>
<h5 class=CodeA>echo "Rebooting..."</h5>
<p class=Code>echo "Want to poke around before coming up all the way?"</p>
<p class=Code>answer=<em class=QCode> `</em> timed-read 60<em class=QCode> `</em> </p>
<p class=Body>Now you could test to see if the answer is <em class=Code>yes</em> or <em class=Code>no</em> .<em class=SpreadSpace> </em>If no one is around, the script will just time out after 60 seconds and the answer will be empty.<em class=SpreadSpace> </em>The shell script could then continue with the rebooting process.</p>
<p class=Body>Surprisingly, there is no simple way for a shell script to wait for a period of time for an answer.<em class=SpreadSpace> </em>The standard solution is to fork off another shell script that sends a signal back to the original shell script that catches the signal and tries to recover.<em class=SpreadSpace> </em>This sounds easy but is fairly difficult to code.<em class=SpreadSpace> </em>And if you are already in a forked process or have forked other processes, it is very tricky to keep everything straight.</p>
<p class=Body>By comparison, the Expect solution is straightforward.<em class=SpreadSpace> </em>In the next chapter, I will show how to make the <em class=Code>expect</em> command strip off the newline automatically.<em class=SpreadSpace> </em>This will make the script even simpler.<a class=footnote href="http://oreilly.com/catalog/expect/chapter/ch03.html#pgfId-10214"><u><font color=#606420>3</font></u></a></p>
</div>
</div>
<div>
<h3 class=HeadA><a name=74021></a>The spawn Command</h3>
<p class=Body>While interacting with a person is useful, most of the time Expect is used to interact with programs.<em class=SpreadSpace> </em>You have already seen enough to get a feeling for <em class=Code>send</em> and <em class=Code>expect</em> .<em class=SpreadSpace> </em>There is more to learn about them, but now I want to explore the <em class=Code>spawn</em> command.</p>
<p class=Body>The <em class=Code>spawn</em> command starts another program.<em class=SpreadSpace> </em>A running program is known as a <em class=Emphasis>process</em> .<em class=SpreadSpace> </em>Expect is flexible and will view humans as processes too.<em class=SpreadSpace> </em>This allows you to use the same commands for both humans and processes.<em class=SpreadSpace> </em>The only difference is that processes have to be spawned first.<a class=footnote href="http://oreilly.com/catalog/expect/chapter/ch03.html#pgfId-10121"><u><font color=#606420>4</font></u></a></p>
<p class=Body>The first argument of the <em class=Code>spawn</em> command is the name of a program to start.<em class=SpreadSpace> </em>The remaining arguments are passed to the program.<em class=SpreadSpace> </em>For example:</p>
<p class=Code>spawn ftp ftp.uu.net</p>
<p class=Body>This command spawns an <em class=Code>ftp</em> process. <em class=Code>ftp</em> sees <em class=Code>ftp.uu.net</em> as its argument.<em class=SpreadSpace> </em>This directs <em class=Code>ftp</em> to open a connection to that host just as if the command "<em class=Code> ftp ftp.uu.net</em> " had been typed to the shell.<em class=SpreadSpace> </em>You can now send commands using <em class=Code>send</em> and read prompts and responses using <em class=Code>expect</em> .</p>
<p class=Body>It is always a good idea to wait for prompts before sending any information.<em class=SpreadSpace> </em>If you do not wait, the program might not be ready to listen and could conceivably miss your commands.<em class=SpreadSpace> </em>I will show examples of this in a later chapter.<em class=SpreadSpace> </em>For now, play it safe and wait for the prompt.</p>
<p class=Body><em class=Code>ftp</em> begins by asking for a name and password. <em class=Code>ftp.uu.net</em> is a great place for retrieving things -- they let anyone use their anonymous <em class=Code>ftp</em> service<em class=Code> .</em> <em class=SpreadSpace></em>They ask for identification (you must enter your e-mail address at the password prompt) but it is primarily for gathering statistics and debugging.</p>
<p class=Body>When I run <em class=Code>ftp</em> by hand from the shell, this is what I see:</p>
<p class=Code>% <em class=Input>ftp ftp.uu.net</em> </p>
<p class=Code>Connected to ftp.uu.net.</p>
<p class=Code>220 ftp.UU.NET FTP server (Version 6.34 Thu Oct 22 14:32:01 EDT 1992) ready.</p>
<p class=Code>Name (ftp.uu.net:don): <em class=Input>anonymous</em> </p>
<p class=Code>331 Guest login ok, send e-mail address as password.</p>
<p class=Code>Password:</p>
<p class=Code>230- Welcome to the UUNET archive.</p>
<p class=Code>230- For information about UUNET, call +1 703 204 8000...</p>
<p class=Code>230- Access is allowed all day...</p>
<p class=Body>&lt; a lot of stuff here omitted &gt;</p>
<p class=Code>230 Guest login ok, access restrictions apply.</p>
<p class=Body>To automate this interaction, a script has to wait for the prompts and send the responses.<em class=SpreadSpace> </em>The first prompt is for a name, to which the script replies "<em class=Code> anonymous\r</em> ".<em class=SpreadSpace> </em>The second prompt is for a password (or e-mail address) to which the script replies "<em class=Code> don@libes.com\r</em> ".<em class=SpreadSpace> </em>Finally, the script looks for a prompt to enter <em class=Code>ftp</em> commands.<em class=SpreadSpace> </em>This looks like "<em class=Code> ftp&gt; </em>".</p>
<p class=Code>expect "Name"</p>
<p class=Code>send "anonymous\r"</p>
<p class=Code>expect "Password:"</p>
<p class=Code>send "don@libes.com\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Body>Notice that each line sent by the script is terminated with <em class=Code>\r</em> .<em class=SpreadSpace> </em>This denotes a return character and is exactly what you would press if you entered these lines at the shell, so that is exactly what Expect has to send.</p>
<p class=Body>It is a common mistake to terminate <em class=Code>send</em> commands to a process followed by <em class=Code>\n</em> .<em class=SpreadSpace> </em>In this context, <em class=Code>\n</em> denotes a linefeed character.<em class=SpreadSpace> </em>You do not interactively end lines with a linefeed.<em class=SpreadSpace> </em>So Expect must not either.<em class=SpreadSpace> </em>Use "<em class=Code> \r</em> ".</p>
<p class=Body>Contrast this to what I was doing earlier -- sending to a user, or rather, standard output.<em class=SpreadSpace> </em>Such strings were indeed terminated with a <em class=Code>\n</em> .<em class=SpreadSpace> </em>In that context, the <em class=Code>\n</em> denotes a newline.<em class=SpreadSpace> </em>Because standard output goes to a terminal, the terminal driver translates this to a carriage-return linefeed sequence.</p>
<p class=Body>Similarly, when reading lines from a program that would normally appear on a terminal, you will see the carriage-return linefeed sequence.<em class=SpreadSpace> </em>This is represented as <em class=Code>\r\n</em> in an expect pattern.</p>
<p class=Body>This may seem confusing at first, but it is inherent in the way UNIX does terminal I/O and in the representation of characters and newlines in strings.<em class=SpreadSpace> </em>The representation used by Tcl and Expect is common to the C language and most of the UNIX utilities.<em class=SpreadSpace> </em>I will have more to say on the subject of newlines and carriage returns in <a class=XRef href="http://oreilly.com/catalog/expect/chapter/send-user.html#72441"></a>.</p>
<p class=Body>Running this script produces almost the same output as when it was run by hand.<em class=SpreadSpace> </em>The only difference is when the program is spawned.<em class=SpreadSpace> </em>When you manually invoke <em class=Command>ftp</em> , you normally see something like:</p>
<p class=Code>% <em class=Input>ftp ftp.uu.net</em> </p>
<p class=Body>Instead <em class=Code>expect</em> shows:</p>
<p class=Code>spawn ftp ftp.uu.net</p>
<p class=Body>The difference is that there is no shell prompt and the string <em class=Code>spawn</em> appears.<em class=SpreadSpace> </em>In <a class=XRef href="http://oreilly.com/catalog/expect/chapter/spawn_cmd.html#24664"></a>, I will show how to customize this string or get rid of it entirely.</p>
<p class=Body>The remainder of the output is identical whether run interactively via the shell or automated via Expect.</p>
<p class=Body>Uunet is a very large repository of public-access on-line information.<em class=SpreadSpace> </em>Among other things stored there are the standards and other documents describing the Internet.<em class=SpreadSpace> </em>These are called RFCs (Request For Comments).<em class=SpreadSpace> </em>For instance RFC 959 describes the FTP protocol and RFC 854 describes the Telnet protocol.<em class=SpreadSpace> </em>These RFCs are all in separate files but stored in one common directory.<em class=SpreadSpace> </em>You can go to that directory using the following commands:</p>
<p class=Code>send "cd inet/rfc\r"</p>
<p class=Body>Each RFC is assigned a number by the publisher.<em class=SpreadSpace> </em>Uunet uses this number to name the file containing the RFC.<em class=SpreadSpace> </em>This means that you have to know the mapping from the title to the number.<em class=SpreadSpace> </em>Fortunately, Uunet has such an index stored as a separate document.<em class=SpreadSpace> </em>You can download this with the following additional commands:</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Code>send "binary\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Code>send "get rfc-index.Z\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Body>The first line waits to make sure that the <em class=Code>ftp</em> server has completed the previous command.<em class=SpreadSpace> </em>The <em class=Code>binary</em> command forces <em class=Code>ftp</em> to disable any translation it might otherwise attempt on transferred files.<em class=SpreadSpace> </em>This is a necessity because the index is not a text file but a compressed file.<em class=SpreadSpace> </em>This format is implied by the <em class=Code>.Z</em> extension in the name.</p>
<p class=Body>The RFCs are named <em class=Code>rfc</em> <em class=Emphasis>###</em> <em class=Code>.Z</em> , where <em class=Emphasis>###</em> is the RFC number.<em class=SpreadSpace> </em>Along with the index, they are all stored in the directory <em class=Code>inet/rfc</em> .<em class=SpreadSpace> </em>By passing the RFC number as an argument, it is possible to add two more commands to download any RFC.</p>
<p class=Code>send "get rfc$argv.Z\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Body>This extracts the number from the command line so that you could call it from the shell as:</p>
<p class=Code>% <em class=Input>ftp-rfc 1178</em> </p>
<p class=Body>Notice that after the <em class=Code>get</em> command is another <em class=Code>expect</em> for a prompt.<em class=SpreadSpace> </em>Even though the script is not going to send another command, it is a good idea to wait for the prompt.<em class=SpreadSpace> </em>This forces the script to wait for the file to be transferred.<em class=SpreadSpace> </em>Without this wait, Expect would reach the end of the script and exit. <em class=Code>ftp</em> would in turn exit, and the file transfer would almost certainly not be completed by then.</p>
<p class=Body><em class=Code>ftp</em> actually has the capability to tell if there were problems in transferring a file, and this capability should be used if you want a robust script.<em class=SpreadSpace> </em>In the interest of simplicity I will ignore this now, but eventually I will start presenting scripts that are more robust.</p>
<p class=Body>However, there is one change for robustness that cannot be ignored.<em class=SpreadSpace> </em>The default timeout is 10 seconds, and almost any <em class=Code>ftp</em> transfer takes at least 10 seconds.<em class=SpreadSpace> </em>The simplest way to handle this is to disable the timeout so that the script waits as long as it takes to get the file.<em class=SpreadSpace> </em>As before, this is done by inserting the following command before any of the <em class=Code>expect</em> commands:</p>
<p class=Code>set timeout -1</p>
<p class=Body>So far this script simply retrieves the RFC from Uunet.<em class=SpreadSpace> </em>As I noted earlier, the file is compressed.<em class=SpreadSpace> </em>Since you usually want to uncompress the RFC, it is convenient to add another line to the script that does this.<em class=SpreadSpace> </em>The <em class=Code>uncompress</em> program is not interactive so it can be called using <em class=Code>exec</em> as:</p>
<p class=Code>exec uncompress rfc$argv.Z</p>
<p class=Body>You could certainly <em class=Code>spawn</em> it, but <em class=Code>exec</em> is better for running non-interactive programs -- you do not have to mess around with <em class=Code>send</em> and <em class=Code>expect</em> .<em class=SpreadSpace> </em>If <em class=Code>uncompress</em> has any problems, Expect reports them on the standard error.</p>
<p class=Body>The final script looks like this:</p>
<p class=Code>#!/usr/local/bin/expect --</p>
<p class=Code><a name="ftp-rfc;rfc, ftp"></a><a name=22280></a># retrieve an RFC (or the index) from uunet via anon ftp</p>
<p class=Code>&nbsp;</p>
<p class=Code>if {[llength $argv] == 0} {</p>
<p class=Code>puts "usage: ftp-rfc {-index|#}"</p>
<p class=Code>exit 1</p>
<p class=Code>}</p>
<p class=Code>set timeout -1</p>
<p class=Code>spawn ftp ftp.uu.net</p>
<p class=Code>expect "Name"</p>
<p class=Code>send "anonymous\r"</p>
<p class=Code>expect "Password:"</p>
<p class=Code>send "don@libes.com\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Code>send "cd inet/rfc\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Code>&nbsp;</p>
<p class=Code>send "binary\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Code>send "get rfc$argv.Z\r"</p>
<p class=Code>expect "ftp&gt; "</p>
<p class=Code>&nbsp;</p>
<p class=Code>exec uncompress rfc$argv.Z</p>
<p class=Body>I have added a comment to the top describing what the script does, and I have also added a check for the arguments.<em class=SpreadSpace> </em>Since the script requires at least one argument, a usage message is printed if no arguments are supplied.</p>
<p class=Body>More checks could be added.<em class=SpreadSpace> </em>For example, if a user runs this script as "<em class=Code> ftp-rfc 1178 1179</em> ", it will not find any such file -- the <em class=Code>get</em> will try to get a file named <em class=Code>rfc1178</em> and save it locally as <em class=Code>1179.Z</em> -- obviously not what the user intended.<em class=SpreadSpace> </em>How might you modify the script to handle this case?</p>
</div>
<div>
<h3 class=HeadA><a name=57614></a>The interact Command</h3>
<p class=Body>All of the uses of Expect so far have been to totally automate a task.<em class=SpreadSpace> </em>However, sometimes this is too rigid.<em class=SpreadSpace> </em>For a variety of reasons you may not want to completely automate a task.<em class=SpreadSpace> </em>A common alternative is to automate some of it and then do the rest manually.</p>
<p class=Body>In the previous example, anonymous <em class=Code>ftp</em> was used to retrieve files automatically from the site <em class=Code>ftp.uu.net</em> .<em class=SpreadSpace> </em>At the beginning of that script was some interaction to identify myself to the <em class=Code>ftp</em> server.<em class=SpreadSpace> </em>This consisted of entering the string <em class=Code>anonymous\r</em> followed by my email address.<em class=SpreadSpace> </em>Here was the Expect fragment to do it:</p>
<p class=Code>expect "Name"</p>
<p class=Code>send "anonymous\r"</p>
<p class=Code>expect "Password:"</p>
<p class=Code>send "don@libes.com\r"</p>
<p class=Body>Now consider doing this manually.<em class=SpreadSpace> </em>If you like to browse through the many computers that support anonymous <em class=Code>ftp</em> , repeating this little identification scenario can be a nuisance.<em class=SpreadSpace> </em>And it seems rather silly since your computer is perfectly capable of supplying this information.<em class=SpreadSpace> </em>This so-called password is not really a <em class=Emphasis>secret</em> password -- it is just an email address.<em class=SpreadSpace> </em>Let Expect do this part while you do the browsing.</p>
<p class=Body>Expect provides a command that turns control from the script over to you.<em class=SpreadSpace> </em>It is named <em class=Code>interact</em> and called as:</p>
<p class=Code>interact</p>
<p class=Body>When this command is executed, Expect stops reading commands from the script and instead begins reading from the keyboard and the process.<em class=SpreadSpace> </em>When you press keys, they are sent immediately to the spawned process.<em class=SpreadSpace> </em>At the same time, when the process sends output, it is immediately sent to the standard output so that you can read it.</p>
<p class=Body>The result is that you are effectively connected directly to the process as if Expect was not even there.<em class=SpreadSpace> </em>Conveniently, when the spawned process terminates, the <em class=Code>interact</em> command returns control to the script.<em class=SpreadSpace> </em>And if you make <em class=Code>interact</em> the last line of the script, then the script itself terminates as well.</p>
</div>
<div>
<h3 class=HeadA><a name=38308></a>Example -- Anonymous ftp</h3>
<p class=Body>The <em class=Code>interact</em> command is ideal for building a script I call <a name="aftp;anonymous ftp"></a><em class=Code>aftp</em> .<em class=SpreadSpace> </em>This script consists of the user/password interaction from the previous example and an <em class=Code>interact</em> command.<em class=SpreadSpace> </em>The complete <em class=Code>aftp</em> script is shown below.</p>
<p class=Body>Anytime you want to begin anonymous <em class=Code>ftp</em> , you can use this little script and it will automatically supply the appropriate identification and then turn control over to you.<em class=SpreadSpace> </em>When you type <em class=Code>quit</em> to <em class=Code>ftp</em> , <em class=Code>ftp</em> will exit, so <em class=Code>interact</em> will exit, and then the script will exit.</p>
<p class=Code>#!/usr/local/bin/expect --</p>
<p class=Code>spawn ftp $argv</p>
<p class=Code>expect "Name"</p>
<p class=Code>send "anonymous\r"</p>
<p class=Code>expect "Password:"</p>
<p class=Code>send "don@libes.com\r"</p>
<p class=Code>interact</p>
<p class=Body>Notice that the script does not wait for "<em class=Code> ftp&gt; </em>" before the <em class=Code>interact</em> command.<em class=SpreadSpace> </em>You could add another <em class=Code>expect</em> command to do that, but it would be redundant.<em class=SpreadSpace> </em>Since the <em class=Code>interact</em> waits for characters from the process as well as the keyboard simultaneously, when the "<em class=Code> ftp&gt; </em>" finally does arrive, <em class=Code>interact</em> will then display it.<em class=SpreadSpace> </em>Presumably, a user will wait for the prompt before typing anyway so there is no functional benefit to using an explicit <em class=Code>expect</em> .</p>
<p class=Body>With only a little more, this script can be jazzed up in lots of ways.<em class=SpreadSpace> </em>For example, rather then embedding your name in the script, you can pull it out of the environment by using the expression <em class=Code>$env(USER)</em> .<em class=SpreadSpace> </em>The full command in the script would be:</p>
<p class=Code>send "$env(USER)@libes.com\r"</p>
<p class=Body>It is a little more difficult to make this script portable to any machine because there is no standard command to retrieve the domain name (presuming you are using domain-name style email addresses, of course).<em class=SpreadSpace> </em>While many systems have a command literally called <em class=Code>domainname</em> , it often refers to the NIS domain name, not the Internet domain name.<em class=SpreadSpace> </em>And the <em class=Code>hostname</em> command does not dependably return the domain name either.</p>
<p class=Body>One solution is to look for the domain name in the file "<em class=Code> /etc/resolv.conf</em> ".<em class=SpreadSpace> </em>This file is used by the name server software that runs on most UNIX hosts on the Internet.<em class=SpreadSpace> </em>Here is a procedure to look up the domain name:</p>
<p class=Code>proc <a name=domainname></a>domainname {} {</p>
<p class=Code>set file [open /etc/resolv.conf r]</p>
<p class=Code>while {[gets $file buf] != -1} {</p>
<p class=Code>if {[scan $buf "domain %s" name] == 1} {</p>
<p class=Code>close $file</p>
<p class=Code>return $name</p>
<p class=Code>}</p>
<p class=Code>}</p>
<p class=Code>close $file</p>
<p class=Code>error "no domain declaration in /etc/resolv.conf"</p>
<p class=Code>}</p>
<p class=Body>The <em class=Code>domainname</em> procedure reads <em class=Code>/etc/resolv.conf</em> until it encounters a line that begins with the string <em class=Code>domain</em> .<em class=SpreadSpace> </em>The rest of the line is returned.<em class=SpreadSpace> </em>If no string is found, or the file cannot be read, an error is generated.</p>
<p class=Body>The full command in the script can now be written as:</p>
<p class=Code>send "$env(USER)@[domainname]\r"</p>
</div>
<div>
<h3 class=HeadA>Exercises</h3>
<ol>
    <li class=Exercise1>The <em class=Code>ftp-rfc</em> script does not understand what to do if the user enters multiple RFC numbers on the command line.<em class=SpreadSpace> </em>Modify the script so that it handles this problem.
    <li class=Exercise>Modify <em class=Code>ftp-rfc</em> so that if given an argument such as "<em class=Code> telnet</em> ", the script first retrieves the index, then looks up which RFCs mention the argument in the title, and downloads them.<em class=SpreadSpace> </em>Cache the index and RFCs in a public directory so that they do not have to be repeatedly downloaded.
    <li class=Exercise>Most <em class=Code>ftp</em> sites use a root directory where only <em class=Code>pub</em> is of interest.<em class=SpreadSpace> </em>The result is that "<em class=Code> cd pub</em> " is always the first command everyone executes.<em class=SpreadSpace> </em>Make the <em class=Code>aftp</em> script automatically <em class=Code>cd</em> to <em class=Code>pub</em> and print the directories it finds there before turning over control to <em class=Code>interact</em> .
    <li class=Exercise>Make the <em class=Code>aftp</em> script <em class=Code>cd</em> to <em class=Code>pub</em> only if <em class=Code>pub</em> exists.
    <li class=Exercise>Write a script to dial a pager.<em class=SpreadSpace> </em>Use it in the error handling part of a shell script that performs a critical function such as backup or <em class=Code>fsck</em> .
    <li class=Exercise>The <em class=Code>domainname</em> procedure on <a class=XRef href="http://oreilly.com/catalog/expect/chapter/ch03.html#domainname"><u><font color=#606420>See proc domainname {} {</font></u></a> is not foolproof.<em class=SpreadSpace> </em>For example, the file <em class=Code>resolv.conf</em> might not exist.<em class=SpreadSpace> </em>Assume the procedure fails on your system and ask <em class=Code>nslookup</em> for the current domainname.
    <li class=Exercise>Write a script that connects to a modem and dials phone numbers from a list until one answers. </li>
</ol>
</div>
</div>
</div>
<hr>
<div class=footnotes>
<div class=footnote>
<p class=Footnote><span class=footnoteNumber>1.</span>It actually reads from standard input which is typically the keyboard.<em class=SpreadSpace> </em>For now, I will treat them as if they were the same thing.</p>
</div>
<div class=footnote>
<p class=Footnote><span class=footnoteNumber>2.</span> You can disable this behavior by saying "<em class=FootNoteCode> stty -icrnl</em> " to the shell, but most programs expect this mapping to take place so learn to live with it.</p>
</div>
<div class=footnote>
<p class=Footnote><span class=footnoteNumber>3.</span>Shell backquotes automatically strip trailing newlines, so the script could be simplified in this scenario just by omitting the "<em class=FootNoteCode> string trimright</em> " command.<em class=SpreadSpace> </em>However, in other contexts it is useful to strip the newlines.</p>
</div>
<div class=footnote>
<p class=Footnote><span class=footnoteNumber>4.</span>Admittedly, humans have to be spawned as well; however, this type of spawning is probably best left to the confines of the bedroom.</p>
</div>
</div>
</blockquote><!-- End of sample chapter -->
<img src ="http://www.cnitblog.com/houcy/aggbug/48324.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2008-08-24 22:10 <a href="http://www.cnitblog.com/houcy/archive/2008/08/24/48324.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)Windows下的Expect</title><link>http://www.cnitblog.com/houcy/archive/2008/08/23/48289.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Sat, 23 Aug 2008 08:59:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2008/08/23/48289.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/48289.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2008/08/23/48289.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/48289.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/48289.html</trackback:ping><description><![CDATA[Expect的主页上说从http://bmrc.berkeley.edu/ftp/pub/winnt/tcltk/expect/expect-5.21r1b1-setup.exe可以下载windows版本的程序，但是我试过多次，一个都没下载成功，提示文件已经不存在。经过几天google，最后终于找到了windows上两种使用Expect的方法。<br><br>方法一：安装ActiveTcl。我安装的是ActiveTcl8.4.15.0.280619-win32-ix86-threaded.exe，它自带了Expect，dll版本是5.43。这种方式下，你只能通过tcl的脚本来实现你想要的Expect功能，事实上为了使用Expect不得不安装一些你可能不需要的功能。<br><br>方法二：安装expect-5.21r1b1-setup.exe。这个文件我是从http://cit.wta.swin.edu.au/cit/subjects/CITP0021/lilydale/downloads/expect-5.21r1b1-setup.exe下载下来的。安装以后，将C:\Program Files\Expect-5.21\bin加入你的搜索路径后就可以在命令行下使用Expect。对于不需要完整的Tcl的功能的用户很适用，因为安装占用很少。 
<img src ="http://www.cnitblog.com/houcy/aggbug/48289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2008-08-23 16:59 <a href="http://www.cnitblog.com/houcy/archive/2008/08/23/48289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)A Tcl/Tk and Expect Tutorial</title><link>http://www.cnitblog.com/houcy/archive/2008/08/23/48288.html</link><dc:creator>挑灯看剑</dc:creator><author>挑灯看剑</author><pubDate>Sat, 23 Aug 2008 08:57:00 GMT</pubDate><guid>http://www.cnitblog.com/houcy/archive/2008/08/23/48288.html</guid><wfw:comment>http://www.cnitblog.com/houcy/comments/48288.html</wfw:comment><comments>http://www.cnitblog.com/houcy/archive/2008/08/23/48288.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/houcy/comments/commentRss/48288.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/houcy/services/trackbacks/48288.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Landmark&nbsp;Graphics&nbsp;Corporation&nbsp;&nbsp;2&nb...&nbsp;&nbsp;<a href='http://www.cnitblog.com/houcy/archive/2008/08/23/48288.html'>阅读全文</a><img src ="http://www.cnitblog.com/houcy/aggbug/48288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/houcy/" target="_blank">挑灯看剑</a> 2008-08-23 16:57 <a href="http://www.cnitblog.com/houcy/archive/2008/08/23/48288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>